2012-10-13 71 views
1

我有在移动设备上这个工作,但因为jQuery的32KB的gzip-ED的我不知道是否有可能创造这个代码这个jQuery可以在vanilla JS中完成吗?

$(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; 
    }); 
}); 

可以在没有图书馆dependany香草的JavaScript编写。

可以这样做吗?我会在哪里开始?

+7

jquery是一个Javascript框架,所以自然你写在jquery中的任何东西都应该在Javascript中可行。 –

+0

像@MatijaMilković说的那样,这个问题的答案永远是肯定的。有时比其他人更难,但jQuery IS JavaScript。 –

回答

18

JQuery使用javascript/DOM脚本来创建其框架。 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

+0

这是不正确的,它替换类似** activeyo **(因为它不检查边界)和** activeyo active-something-else **(因为g标志),但它*不*匹配**主动**(因为它没有领先的空间)。 – chelmertz

+1

@chelmertz:我说'*类似*'。但你是对的,不好的例子。用更好的答案编辑答案。 – KooiInc

+0

我刚刚学会了〜操作符的第一个有用的javascript用法!英勇! – Joehannes

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

仅适用于现代浏览器。 ®

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); 
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); 
    } 
});