Skip to content

从阅读JQuery源码中发现的18个惊奇的地方

jnotnull edited this page Jul 24, 2014 · 11 revisions

原文链接:http://quickleft.com/blog/18-surprises-from-reading-jquery-s-source-code 翻译:jnotnull


我喜欢JQuery,虽然我自认为自己试JS的高级开发人员,但是之前一直没有从头到尾的度过它的源码。最近有机会读了它的源码,并记录下来我学到的东东。

注:我对元素调用方法使用$.fn.method()语法。比如,如果我说$.fn.addClass,则意味着,要使用$(‘div’).addClass(‘blue’) 或者 $(‘a.active’).addClass(‘in-use’)。$.fn是jQuery对象的原型对象。

1.Sizzle在jQuery中的分量:Sizzle是jQuery的选择器引擎。它基于CSS选择器,用于查找DOM中的元素。它能转换$(‘div.active’)为一组元素数组。我之前知道Sizzle在JQuery中占有很大的分量,但是我却不知道分量有这么大。它显然已经是jQuery中最大的特性了。按照我的计算,他已经占有22%的代码量。而第二大特性$.ajax仅仅占到了8%。显然高出了很多。

2.$.grep:这个方法类似于Underscore的_.filter。它有两个参数,分别是数据集合和回调方法。返回值是过滤后的集合。

3.事件冒泡的注意事项:jQuery中load事件是不能进行冒泡的。事实上,jQuery传递了一个参数noBubble为true的值给了load事件。因此image.load事件不会冒泡到window(这个可能会和window.load事件搞混淆了)

4.默认的动画渲染频率:jQuery动画元素是通过快速改变其样式属性而形成的。每一个这样的变化称为“帧”。默认的动画速度是每帧13毫秒,你可以重写jQuery.fx.interval来调整渲染频率。

5.$.fn.addClass可以接受方法作为参数:我们通常传递一个string型的class名称去新增样式。但是这个方法也可以接受方法,返回值是带有-分割的class名称。这个class名称会作用到匹配的元素上。当然,这个方法需要接受一个元素索引作为参数,一遍更加智能。

6.$.fn.removeClass同样:这个也可以接受一个方法,和上面提到的一样,这个方法也能够接受元素的索引作为参数。

7.:empty伪选择器:这个方便的选择器不能匹配子节点(译者注:也不能匹配文本节点)

8.:lt和:gt选择器:这个选择器是根据查找到的元素的索引来匹配的。比如$(‘div:gt(2)’)将会返回所有索引大于2的div(数字是从0开始的)。如果你传的是负值,则从反方向开始。

9.$(document).ready()使用了promise:jQuery eats its own dog food, it would seem.事实上$(document).ready()使用了延迟加载,他要等到DOM都加载完成后才执行。

10.$.type:我们对typeof判断诗句类型非常熟悉,但是你知道jQuery提供了一个.type()方法么。jQuery这个版本更加智能。举个例子:typeof (new Number(3))得到的是object类型,而$.type(new Number(3))得到的number类型。正如ShirtlessKirk 之处的是,$.type返回的是传递值的.valueOf()属性的类型。因此它会更加准确的判断数据类型。

11.$.fn.queue:你可以使用如下代码实现元素的效果队列:$(‘div’).queue()。这对于像知道还有多少效果没渲染非常有用。甚至你还可以直接添加效果到这个队列中。jQuery文档中的例子

$( document.body ).click(function() {
$( "div" )
  .show( "slow" )
  .animate({ left: "+=200" }, 2000 )
  .queue(function() {
    $( this ).addClass( "newcolor" ).dequeue();
  })
  .animate({ left: "-=200" }, 500 )
  .queue(function() {
    $( this ).removeClass( "newcolor" ).dequeue();
  })
  .slideUp();
});

12.disabled的元素禁止click事件:jQuery不会处理disabled元素的click事件。如果你想支持,则必须自己写代码去实现了。

13.$.fn.on可以接受一个对象:你知道$.fn.on可以接受一个对象来添加多个事件么?下面是jQuery文档中的例子:

$( "div.test" ).on({
click: function() {
  $( this ).toggleClass( "active" );
}, mouseenter: function() {
  $( this ).addClass( "inside" );
}, mouseleave: function() {
  $( this ).removeClass( "inside" );
}
});

14.$.camelCase:这个是一个转换-到骆驼命名的非常有用的方法。

15.$.active:调用$.active会获得当前活动的XHR请求个数。这个可以用于限制一次最懂同时请求多少个数的限制。

16.$.fn.parentsUntil / $.fn.nextUntil / $.fn.prevUntil:我对.parents(), .next() 和 .prev()方法非常熟悉,但是我不知道还有这些方法。本质上,他们会匹配所有的元素知道他们碰到停止元素。

17.$.fn.clone参数:当你.clone()一个元素,你可以把把方法的第一个参数置为true,就还可以克隆它的数据属性和事件。

18.$.fn.clone的其他参数:补充上面说的,你还可以通过传递第二个参数为true,来克隆他的子节点的数据属性和事件。这被称为深度克隆。第二个参数的默认和第一个相同(都是false),所以如果你第一个参数是true,如果你想第二个参数也是true,则你可以不用传递第二个参数的。

Clone this wiki locally