虽然我已经做网站建设工作10多年了,但我从最近3年才开始更多地学习如何更好的将纯JavaScript用于工作中,而不总是将jQuery考虑在第一位。现在我每天学习很多东西。这个过程让我觉得Adtile的JavaScript SDK 更像是在创建一个开源工程,而不是“具体的工作”,不得不说,我很喜欢那样。
今天,我准备将在过去几年学到的一些基础东西与大家一起分享,这将可能帮你深入纯 JavaScript的世界,让你能更简单的做出决定——jQuery在你下个工程中是否需要。
虽然像jQuery这样的库有助于解决许多浏览器之间不兼容的问题,但当你一旦开始使用纯JavaScript来完成所有工作的时候你确实会变得对他们很熟悉。为了避免写包含浏览器修改和只能解决浏览器兼容问题的JavaScript代码,我建议使用特征检测只将更现代化的浏览器作为目标来培养逐步增强的经验。这并不意味着从像IE7这样的浏览器上得不到任何东西,这只能说明在JavaScript没有增强的情况下他们得到一个更基础的经验。
我们是怎么做的
我们有一个叫做”feature.js”的分离的JavaScript部分,它拥有所有的功能测试。真实的测试列表比这长多了,但让我们稍晚点再回到这问题吧。为了消除一些老浏览器的不兼容,我们使用如下两个测试:
var feature = { addEventListener : !!window.addEventListener, querySelectorAll : !!document.querySelectorAll, };然后,在主应用程序部分,我们检测这些特性是否能被下面例子中简单的“if”语句支持。如果不被支持,那么浏览器将不会执行如下的任何代码:
if (feature.addEventListener && feature.querySelectorAll) { this.init(); }这两个测试确保我们在JavaScript中使用CSS选择器时有本地方法(querySelectorAll)可用,添加和删除事件的简便方法(addEventListener)且浏览器标准支持比IE8的好。阅读有关这个方法的更多内容请访问BBC blog的 “Cutting the mustard” 文章。
这儿有一个我们测试的哪些浏览器支持这个特性,且日后能保持运行JavaScript的粗略列表:
让我们开始关注与jQuery相比,最基础且需求频繁的功能在纯JavaScript中是如何工作的。对于每个例子,我都打算提供jQuery和纯JavaScript两种方法。Document Ready 事件
在jQuery中,你们中的许多人可能过去常常像这样使用 document.ready :
$(document).ready(function() { // Code });但是你知道,你可以将所有的JavaScript放在页面的底端,但他们确实是一回事吗?JavaScript同样拥有一个DOM内容加载事件的侦听器,而不是使用jQuery的document.ready:
document.addEventListener("DOMContentLoaded", function() { // Code }, false);选择器APIJavaScript的本地选择器API非常优秀。它对CSS选择器是有用的且jQuery提供的非常类似。如果你过去经常在jQuery中这样写:
var element = $("div");现在你可以用如下的语句来替代:
var element = document.querySelector("div");或者选择所有div的某些内部容器:
var elements = document.querySelectorAll(".container div");你也可以针对特定元素进行查询来找到它的子元素:
var navigation = document.querySelector("nav"); var links = navigation.querySelectorAll("a");很简单,容易理解且现在不需要太多的代码,不是吗?更远一步来说,我们甚至可以自己建一个小型的JavaScript库来进行简单的DOM查询。以下是Andrew Lunny:
// This gives us simple dollar function and event binding var $ = document.querySelectorAll.bind(document); Element.prototype.on = Element.prototype.addEventListener; // This is how you use it $(".element")[0].on("touchstart", handleTouch, false);遍历DOM用纯JavaScript来遍历DOM比起用jQuery来说有一些困难。但也不是太困难。下面是一些简单的例子:
// Getting the parent node var parent = document.querySelector("div").parentNode;// Getting the next node var next = document.querySelector("div").nextSibling;// Getting the previous node var next = document.querySelector("div").previousSibling;// Getting the first child element var child = document.querySelector("div").children[0];
// Getting the last child var last = document.querySelector("div").lastElementChild;
添加和删除样式名(class name)使用jQuery,添加、删除和检查一个元素是否有确定的类是很简单的事。用纯JavaScript会有一些复杂,但也不是太复杂。给元素一个叫做“foo”的类且替换目前所有的类:
// Select an element var element = document.querySelector(".some-class");// Give class "foo" to the element element.className = "foo";
在不替换目前类的前提下增加类:
element.className += " foo";从html元素中移除”no-js”类且用”js”来替代:
<html> <head> <script> document.documentElement.className = "js"; </script>这相当简单,对不对?下一步,只移除某些类稍微有点复杂。我一直在单独部分使用这个叫做util.js的小助手函数。它有两个参数:元素和你想移除的类:
// removeClass, takes two params: element and classname function removeClass(el, cls) { var reg = new RegExp("(\\s|^)" + cls + "(\\s|$)"); el.className = el.className.replace(reg, " ").replace(/(^\s*)|(\s*$)/g,""); }然后,在主应用程序部分,我一直像这样使用:
removeClass(element, "foo");如果针对某些类你同样想检查一个元素,那么就像jQuery的hasClass一样。你可能需要把这些代码加入到你的utils工具中:
// hasClass, takes two params: element and classname function hasClass(el, cls) { return el.className && new RegExp("(\\s|^)" + cls + "(\\s|$)").test(el.className); }