From jQuery to Vanilla JS 2019-03-19

Some ideas to remove jQuery and replace it with standard VanillaJS functions

A long time it was really a mess to develop for different browsers. Even standard functionality like makine Ajax calls was not implemented in a standard way a long time (Yes, IE, I look at you!).

That was the time where jQuery really shined: It abstracted away all that browser-specific fuzz and made a developer's life really much easiert.

That time has gone, in my opinion. Nowadays many functions can be implemented in Vanilla JavaScript. This entry collects some few techniques to remove jQuery functions and replace them with Vanilla JS functions.

All methods here should work on modern browsers, and, yes, on some older, too: IE >= 9 should support all those approaches. If in doubt, have a look at https://caniuse.com/ .

Selecting elements

In jQuery, you could easily fetch element(s) by a CSS selector:

$('some-fancy-selector');

With element.querySelector / element.querySelectorAll you could easily do the same without jQuery:

// First element that match the selector:
var oneElement = document.querySelector('.main ul a');

// all elements that matches the selector:
var allElements = document.querySelectorAll('.main ul a');

// This even works on selected elements (so only look at a part of the DOM tree):
var child = element.querySelector('a.active');

show / hide / toggle elements

In jQuery you can use to change the display of an element:

$('#my-element').hide();
$('#my-element').show();
$('#my-element').toggle();

This basically sets the display css property. The problem here is that for initially-none-display elements, a show needs to make an assumption what value display should get. This can be assumed, or given the show function:


/**
 * Shows a DOM element by setting the "display" css value to either '' or the given value
 *
 * @param DOMElement el
 * @param string display
 */
function show(el, display) {
    var oldDisplay = el.getAttribute('data-orig-show') || display || '';
    if (oldDisplay === 'none') {
        oldDisplay = display || '';
    }
    el.style.display = oldDisplay;
}

/**
 * Hides a DOM element by setting the "display" css value to 'none'
 *
 * @param DOMElement el
 */
function hide(el) {
    var display = el.style.display || '';
    el.setAttribute('data-orig-show', display);
    el.style.display = 'none';
}

/**
 * Toggles a DOM element by setting the diplay value to 'none' or the given default ('block' if not given)
 *
 * @param DOMElement el
 * @param string display
 */
function toggle(el, display) {
    if (el.style.display !== 'none') {
        hide(el);
    } else {
        show(el, display);
    }
}

// Usage:
var el = document.getElementById('meElement');
hide(el);
show(el);
toggle(el);

Ajax calls

A simple VanillaJS ajax function:

/**
 * Dependenfy-free Ajax function. Takes an option object with the following properties:
 *
 * - url: The request URL
 * - method: HTTP Method (defaults go 'GET')
 * - params: An object with request params, which will be url-encoded and appended to either the request URL (GET) or as POST body.
 * - success/failure/callback: A callback function that is called after the request was successful/failed (callback is called always).
 *     The original xhr request is provided as parameter, containing the response.
 * - responseType: either 'text' or 'json': If json is given, the responseText will be parsed and stored as xhr.responseJSON object in the response.
 */
function ajax(opts) {
    var url = opts.url;
    var method = (opts.method || 'GET').toUpperCase();
    var params = opts.params || {};
    var success = opts.success || function(){};
    var failure = opts.failure || function(){};
    var callback = opts.callback || function(){};
    var responseType = ( opts.responseType || 'text' ).toLowerCase();

    var xhr = new XMLHttpRequest();
    var paramString = Object.keys(params).map(function(k){
        return encodeURI(String(k) + '=' + String(params[k]));
    }).join('&');
    if (method === 'GET') {
        if (url.indexOf('?') > -1) {
            url += '&'
        } else {
            url += '?';
        }
        url += paramString;
    }
    xhr.open(method, url);
    xhr.onload = function() {
        if (xhr.status === 200) {
            if (responseType === 'json') {
                try {
                    xhr.responseJSON = JSON.parse(xhr.responseText);
                } catch(e) {
                    //noop
                }
            }
            success(xhr);
        }
        else {
            failure(xhr);
        }
        callback(xhr);
    };
    xhr.send(paramString);
    return xhr;
}