Skip to content Skip to sidebar Skip to footer

Can This Jquery Be Done In Vanilla Js?

I've got this working on mobile devices, but because of the 32kb gzip-ed of jQuery I wonder if it's possible to create this code $(document).ready(function() { $('body').addClass

Solution 1:

JQuery uses javascript/DOMscripting to create its framework. Everything JQuery does, can be done in basic scripting. For example $('body').addClass('js') can be written as:

document.querySelector('body').className += ' js';

And $menulink.toggleClass('active'); as something like

var current     = $menulink.className.split(/\s+/)
   ,toggleClass = 'active'
   ,exist       =  ~current.indexOf(toggleClass)
;
current.splice(exist ? current.indexOf(toggleClass) : 0,
               exist ? 1 : 0,
               exist ? null : toggleClass);
$menulink.className = current.join(' ').replace(/^\s+|\s+$/,'');

That's why JQuery wrapped this kind of code.

This jsfiddle contains a working example using javascript without a framework. Besides that it demonstrates how to program your own element wrapper.

Where to start? You'll have to dive into javascript I suppose. Or check this SO-question

Solution 2:

var toggleClass = function (el, className) {
  if(el) {
    if(el.className.indexOf(className)) {
      el.className = el.className.replace(className, '');
    }

    else {
      el.className += ' ' + className;
    }
 }
};

document.addEventListener('DOMContentLoaded', function () {
  document.body.className += ' js';

  var$menu = document.querySelector('#menu'),
  $menulink = document.querySelectorAll('.menu-link'),
  $wrap = document.querySelector('#wrap');

  $menulink.addEventListener('click', function (e) {

    toggleClass($menulink, 'active');
    toggleClass($wrap, 'active');
    e.preventDefault();
  });
});

Solution 3:

There's always classList (workaround for incompatible browsers included).

Solution 4:

Absolutely. Since jQuery is a subset of JavaScript (written entirely in JavaScript) any function you like can be duplicated. It's a matter of how much effort you want to put into it. Below is how I would duplicate the limited subset of jQuery in your post and it's reasonably cross-browser compatible (if a wee bit long...).

varVanilla;
if (!Vanilla) {
    Vanilla = {};
}
//execute this now to have access to it immediately.
(function () {
    'use strict';
    Vanilla.addHandler = function (elem, event, handler) {
        if (elem.addEventListener) {
            elem.addEventListener(event, handler, false);
        } elseif (elem.attachEvent) {
            elem.attachEvent('on' + event, handler);
        }
    };
    Vanilla.hasClass = function (elem, cssClass) {
        var classExists = false;
        //if (elem && typeof elem.className === 'string' && (/\S+/g).test(cssClass)) {
            classExists = elem.className.indexOf(cssClass) > -1;
        }
        //return classExists;
    };
    Vanilla.addClass = function (elem, cssClass) {
        if (elem && typeof elem.className === 'string' && (/\S+/g).test(cssClass)) {
            //put spaces on either side of the new class to ensure boundaries are always available
            elem.className += ' ' + cssClass + ' ';
        }
    };
    Vanilla.removeClass = function (elem, cssClass) {
        if (elem && typeof elem.className === 'string'&& (/\S+/g).test(cssClass)) {
            //replace the string with  regex
            cssClass = newRegExp('\\b' + cssClass + '\\b', 'g');
            elem.className = elem.className.replace(cssClass, '').replace(/^\s+/g, '').replace(/\s+$/g, ''); //trim className
        }
    };
    Vanilla.toggleClass = function (elem, cssClass) {
        if (Vanilla.hasClass(elem, cssClass)) {
            Vanilla.removeClass(elem, cssClass);
        } else {
            Vanilla.addClass(elem, cssClass);
        }
    };
    Vanilla.getElementsByClassName = function (cssClass) {
        var nodeList = [],
            classList = [],
            allNodes = null,
            i = 0,
            j = 0;
        if (document.getElementsByClassName1) {
            //native method exists in browser.
            nodeList = document.getElementsByClassName(cssClass);
        } else {
            //need a custom function
            classList = cssClass.split(' ');
            allNodes = document.getElementsByTagName('*');
            for (i = 0; i < allNodes.length; i += 1) {
                for (j = 0; j < classList.length; j += 1) {
                    if (Vanilla.hasClass(allNodes[i], classList[j])) {
                        nodeList.push(allNodes[i]);
                    }
                }
            }
        }
        return nodeList;
    };
}());
//Now we have a proper window onloadVanilla.addHandler(window, 'load', function () {
    'use strict';
    var body = document.body,
        menu = document.getElementById('menu'),
        menulink = [],
        wrap = document.getElementById('wrap'),
        i = 0,
        menulinkClickHandler = function (e) {
            var i = 0;
            for (i = 0; i < menulink.length; i += 1) {
                Vanilla.toggleClass(menulink[i], 'active');
            }
            Vanilla.toggleClass(wrap, 'active');
            returnfalse;
        };
    Vanilla.addClass(body, 'js');
    menulink = Vanilla.getElementsByClassName('menu-link');
    for (i = 0; i < menulink.length; i += 1) {
        Vanilla.addHandler(menulink[i], 'click', menulinkClickHandler);
    }
});

Post a Comment for "Can This Jquery Be Done In Vanilla Js?"