Skip to content

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

jnotnull edited this page Jul 17, 2014 · 11 revisions

I love jQuery, and though I consider myself an advanced JavaScript developer, I had never read the jQuery source from top to bottom, until now. Here are a few things that I learned along the way: 我喜欢JQuery,虽然我自认为自己试JS的高级开发人员,但是之前一直没有从头到尾的度过它的源码。最近有机会读了它的源码,并记录下来我学到的东东。

Note: I use the $.fn.method() syntax to refer to the practice of calling method on a set of matched elements. For example, when I say $.fn.addClass, that represents uses like $(‘div’).addClass(‘blue’) or $(‘a.active’).addClass(‘in-use’). $.fn is the prototype for jQuery-wrapped elements. 注:我对元素调用方法使用$.fn.method()语法。比如,如果我说$.fn.addClass,则意味着,要使用$(‘div’).addClass(‘blue’) 或者 $(‘a.active’).addClass(‘in-use’)。$.fn是jQuery对象的原型对象。

Sizzle’s weight: Sizzle is the selector engine jQuery uses to find elements in a DOM based on CSS selectors. It’s what turns $(‘div.active’) into an array of elements you can operate on. I knew Sizzle made up a large portion of jQuery, but I was surprised at just how massive it really is. It’s easily the single biggest feature, line-count wise, in jQuery source. By my calculations it makes up 22% of the overall codebase. That dwarfs the next biggest feature in jQuery—$.ajax—which makes up just 8% of the library’s codebase. Sizzle在jQuery中的分量:Sizzle是jQuery的选择器引擎。它基于CSS选择器,用于查找DOM中的元素。它能转换$(‘div.active’)为一组元素数组。我之前知道Sizzle在JQuery中占有很大的分量,但是我却不知道分量有这么大。它显然已经是jQuery中最大的特性了。按照我的计算,他已经占有22%的代码量。而第二大特性$.ajax仅仅占到了8%。显然高出了很多。

$.grep: This method is similar to Underscore’s .filter in that it takes two arguments, an array of elements and a function, and returns the elements that pass the function’s truth test. $.grep:这个方法类似于Underscore的.filter。它有两个参数,分别是数据集合和回调方法。返回值是过滤后的集合。

Bubbling caveats: jQuery specifically prohibits one type of event from ever bubbling. That is the load event. Internally, jQuery passes a special noBubble: true flag through with any load events, so that image.load events can’t bubble up to the window (which could mistakenly match a window.load event). 事件冒泡的注意事项:jQuery中load事件是不能进行冒泡的。事实上,jQuery传递了一个参数noBubble为true的值给了load事件。因此image.load事件不会冒泡到window(这个可能会和window.load事件搞混淆了)

Default animation speed: jQuery animates elements by changing their style attributes in quick succession. Each of these changes is called a “tick.” The default animation speed is to run a tick every 13 milliseconds, and you can adjust this by overriding jQuery.fx.interval with your own integer. 默认的动画渲染频率:jQuery动画元素是通过快速改变其样式属性而形成的。每一个这样的变化称为“帧”。默认的动画速度是每帧13毫秒,你可以重写jQuery.fx.interval来调整渲染频率。

$.fn.addClass accepts a function: We usually supply $.fn.addClass with a string of class names to add to an element. But it can also accept a function. You must return a string of comma-separated class names from this function to apply them to the matched element. As a bonus, this function receives the matched element’s index as an argument, which you can use to build intelligent class names. $.fn.addClass可以接受方法作为参数:我们通常传递一个string型的class名称去新增样式。但是这个方法也可以接受方法,返回值是带有-分割的class名称。这个class名称会作用到匹配的元素上。当然,这个方法需要接受一个元素索引作为参数,一遍更加智能。

So does $.fn.removeClass: This also accepts a function, like the method mentioned above. This function also automatically receives the element’s index. $.fn.removeClass同样:这个也可以接受一个方法,和上面提到的一样,这个方法也能够接受元素的索引作为参数。

:empty pseudo selector: This convenient pseudo selector will match elements with no children. :empty伪选择器:这个方便的选择器不能匹配子节点(译者注:也不能匹配文本节点)

:lt and :gt pseudo selectors: These pseudo selectors match elements based on their index in the matched set. For example, $(‘div:gt(2)’) will return all divs except for the first three (numbers are zero-indexed). If you supply a negative integer as the argument, it counts backwards starting from the end of the set. :lt和:gt选择器:这个选择器是根据查找到的元素的索引来匹配的。比如$(‘div:gt(2)’)将会返回所有div中的前三个(数字是从0开始的)。如果你传的是负值,则从反方向开始。

$(document).ready() uses a promise: jQuery eats its own dog food, it would seem. Internally, trusty ol’ $(document).ready() uses a jQuery deferred to determine when the DOM is fully loaded. $(document).ready()使用了promise:jQuery eats its own dog food, it would seem.事实上$(document).ready()使用了延迟加载,他要等到DOM都加载完成后才执行。

$.type: I’m sure we’re all familiar with typeof to determine what data type something is, but did you know jQuery provides a .type() method? jQuery’s version is more intelligent than the native browser version. For example, typeof (new Number(3)) returns “object,” whereas $.type(new Number(3)) returns “number.” Update: As ShirtlessKirk pointed out in the comments, $.type returns the type of the .valueOf() property of the receiving object. So it's more accurate to say that $.type tells you the type of the return value for an object. $.type:我们对typeof判断诗句类型非常熟悉,但是你知道jQuery提供了一个.type()方法么。jQuery这个版本更加智能。举个例子:typeof (new Number(3))得到的是object类型,而$.type(new Number(3))得到的number类型。正如ShirtlessKirk 之处的是,$.type返回的是传递值的.valueOf()属性的类型。因此它会更加准确的判断数据类型。

$.fn.queue: You can inspect an element’s effects queue with the following example code: $(‘div’).queue(). This is useful if you need to know how many effects are remaining on an element. Even more useful, you can directly manipulate the queue to add your own effects. From the jQuery docs: $.fn.queue:如果你期望一个元素的效果

$( 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(); }); Click events prohibited on disabled elements: jQuery automatically won’t process click events on disabled elements, a nice optimization to save you from having to write your code to check against this scenario.

$.fn.on accepts an object: Did you know that $.fn.on accepts an object to attach multiple events at once? An example from the jQuery docs:

$( "div.test" ).on({ click: function() { $( this ).toggleClass( "active" ); }, mouseenter: function() { $( this ).addClass( "inside" ); }, mouseleave: function() { $( this ).removeClass( "inside" ); } }); $.camelCase: This utility method converts dashed-strings to camelCased strings.

$.active: Calling $.active returns the number of active XHR queries. This can be useful for enforcing limits to how many in-flight AJAX requests you’ll allow at once.

$.fn.parentsUntil / $.fn.nextUntil / $.fn.prevUntil: I was very familiar with the .parents(), .next(), and .prev() methods, but I didn’t know these other versions existed. Essentially, they’ll match all parents/next elements/previous elements until they encounter your stop-condition element.

$.fn.clone arguments: When you .clone() an element, you can also clone its data attributes and events by passing true as the first argument to clone.

More $.fn.clone arguments: In addition to the above, you can clone its children’s data attributes and events by passing an additional true argument. This is called a "deep clone." That second argument defaults to the value of the first (whose default is false). So if the first is true and you want the second to be true, you can omit the second argument entirely.

Clone this wiki locally