这个jQuery可以用vanilla JS完成吗?

时间:2012-10-13 14:24:01

标签: javascript jquery toggleclass

我已经在移动设备上工作,但由于jQuery的32kb gzip-ed,我想知道是否可以创建此代码

$(document).ready(function() {
  $('body').addClass('js');

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

    $menulink.click(function() {
        $menulink.toggleClass('active');
        $wrap.toggleClass('active');
        return false;
    });
});

可以写成没有库依赖任何香草JavaScript。

可以吗?我从哪里开始?

5 个答案:

答案 0 :(得分:18)

JQuery使用javascript / DOMscripting来创建其框架。 JQuery所做的一切都可以在基本脚本中完成。例如,$('body').addClass('js')可以写成:

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

$menulink.toggleClass('active');类似

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+$/,'');

这就是JQuery包装这种代码的原因。

This jsfiddle包含一个使用没有框架的javascript的工作示例。除此之外,它演示了如何编写自己的元素包装器。

从哪里开始?我想你必须dive into javascript。或者查看此SO-question

答案 1 :(得分:3)

仅适用于现代浏览器.®

document.addEventListener('DOMContentLoaded', function() {
    document.body.classList.add('js');

    var wrap = document.getElementById('wrap');
    var menuLinks = Array.prototype.slice.call(document.getElementsByClassName('menu-link'));

    var toggleActive = function(element) {
        element.classList.toggle('active');
    };

    menuLinks.forEach(function(menuLink) {
        menuLink.addEventListener('click', function(e) {
            menuLinks.forEach(toggleActive);
            toggleActive(wrap);
        }, false);
    });
}, false);

答案 2 :(得分: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();
  });
});

答案 3 :(得分:1)

总是classList(包含不兼容浏览器的解决方法)。

答案 4 :(得分:0)

绝对。由于jQuery是JavaScript的一个子集(完全用JavaScript编写),因此您可以复制任何您喜欢的函数。这是你想要投入多少努力的问题。下面是我如何在你的帖子中复制jQuery的有限子集,它是合理的跨浏览器兼容(如果有点长......)。

var Vanilla;
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);
        } else if (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 = new RegExp('\\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 onload
Vanilla.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');
            return false;
        };
    Vanilla.addClass(body, 'js');
    menulink = Vanilla.getElementsByClassName('menu-link');
    for (i = 0; i < menulink.length; i += 1) {
        Vanilla.addHandler(menulink[i], 'click', menulinkClickHandler);
    }
});
相关问题