如今,jQuery已经大量普及,jQuery代码写起来很方便,人人都会写。
但是在大量js代码的情况下,还是要注意一些性能方面的问题。
本系列文章将会讲述如何使用jQuery来写出高性能的jQuery代码。
下面就对jQuery中最常用的事件绑定做一些补充。
jQuery中事件绑定很简单
$("#id1").click(function(){
alert(123);
});
这样就完成了对id为id1的元素的click事件的绑定
但是当类似的绑定事件越来越多,甚至几百个的时候。性能问题就凸显出来了。
而且有些情况下,不知不觉就绑定了几百个事件
$("li", "#infoList1").click(function(){
alert(123);
});
实际情况中,经常会出现对li这类元素的事件绑定,而这些li又是通过php循环生成出来的。
如果后台代码循环了100个这样的li,那么不知不觉中就绑定了100个click事件。
而如果这样的代码在一个页面的js代码中多次出现,那性能可想而知。
一种改进方式:
$("#infoList1").click(function(e){
var $target = $(e.target);
if (!$target.is("li")) {
return false; // 忽略任何不是li元素的click事件
}
// code here
});
用以上方式直接绑定li元素的父节点或者祖先节点。这里只绑定了一个click事件,无论infoList1下的li有多少个。
如上的方式虽好,但是如果infoList1下面还有其他多个元素需要绑定事件,那么代码中会变成这样
$("#infoList1").click(function(e){
var $target = $(e.target);
if ($target.is("li")) {
// li click handler
} else if ($target.is("a")) {
// a click handler
} else if ($target.is("input:button")) {
// button click handler
}
// ... 以下多个其他元素的click事件处理
});
这还只是针对一个click事件的判断,如果有其他事件,其他事件也得这样判断,这样虽说提高了性能但是代码变复杂,变不清晰了。
其实,jQuery中早就提供了解决方案,那就是被众人遗弃、鄙视、误解的live函数
$("li", "#infoList1").live("click", function(){
// li click handler
});
$("a", "#infoList1").live("click", function(){
// a click handler
});
对于市面上的一些误解,就不多说了,直接看官方文档怎么说
The .live()
method is able to affect elements that have not yet been added to the DOM through the use of event delegation: a handler bound to an ancestor element is responsible for events that are triggered on its descendants. The handler passed to .live()
is never bound to an element; instead, .live()
binds a special handler to the root of the DOM tree. In our example, when the new element is clicked, the following steps occur:
- A click event is generated and passed to the
<div>
for handling. - No handler is directly bound to the
<div>
, so the event bubbles up the DOM tree. - The event bubbles up until it reaches the root of the tree, which is where
.live()
binds its special handlers by default. * As of jQuery 1.4, event bubbling can optionally stop at a DOM element "context". - The special
click
handler bound by.live()
executes. - This handler tests the
target
of the event object to see whether it should continue. This test is performed by checking if$(event.target).closest('.clickme')
is able to locate a matching element. - If a matching element is found, the original handler is called on it.
Because the test in step 5 is not performed until the event occurs, elements can be added at any time and still respond to events.
文档地址
jQuery中还有一种写法,和live有异曲同工之妙
$("#infoList1").delegate("li", "click", function(){
// li click handler
});