当前位置:嗨网首页>书籍在线阅读

42-讨论

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

8.10.3 讨论

1.为什么事件处理程序不见了

和CSS相反,JavaScript不是一种声明性的语言。不用描述各种行为,它们都会“像魔术一样自动”应用。

JavaScript和许多其他语言一样是命令式语言。开发人员指定需要执行的一系列操作,这些操作在代码执行到该行的时候应用。

当添加如下这段代码时:

function handler(){
   alert('got clicked');
}
jQuery('.clickable').bind('click', handler);

下面就是所要做的:

1.查找所有CSS类为“clickable”的元素,将其保存在集合里。

2.将“处理程序”函数绑定到集合中每个元素的单击事件。

如果JavaScript/jQuery进行声明性的解释,上述代码的意思如下:

每当单击CSS类为 clickable 的元素,就运行 handler 函数。

但是,因为JavaScript/jQuery的解释是命令式的,只有在运行时匹配选择器的元素才会绑定。如果用 clickable 类添加新元素或者从元素上删除该类,不会添加或者删除这些元素的行为。

2.事件委托简介

事件委托就是在开始时绑定一次,然后被动地监听事件的触发。它依赖浏览器中的许多事件都会冒泡这一事实。

举一个例子,在单击一个 <div> 之后,它的双亲节点也会接收单击事件,然后传递给双亲的双亲,依此类推直到它到达 document 元素。

3.每种方法的优点和缺点

重新绑定 。重新绑定很简单:你只是重新添加事件处理程序。它会导致新的问题,例如,为已经绑定事件处理程序的元素添加事件处理程序。有些人添加CSS类来解决这一问题(用某个类标记已经绑定的元素)。

所有这些处理在每次元素更新的时候都需要CPU周期,而且需要创建越来越多的事件处理程序。

同时解决这两个问题的方法之一是使用命名函数作为事件处理程序。如果你始终使用同一个函数,就已经解决了重复的问题,开销也较小。

但是,重新绑定仍然可能随着时间的推移导致越来越高的内存消耗。

事件委托 。事件委托只要求在开始的时候绑定,完全没有必要处理重新绑定。这对于开发人员来说相当轻松,而且使代码更加简短,也更加清晰。前面提到的RAM问题不适用于事件委托。页面的内容可能变化,但是活动的事件处理程序总是相同。

但是,事件委托也有需要小心的地方。为了使其正常工作,处理代码( live() 、插件或者你自己的代码)必须取得发生事件的元素( event.target )并遍历它的祖先元素,查看哪一个元素有可以触发的事件处理程序,此外还有一些其他的处理。这意味着,虽然事件委托需要的绑定较少,但是每次触发事件时需要更多的处理。

而且,事件委托无法用于不进行冒泡的事件,例如, focusblur 。对于这些事件来说,有一个跨浏览器的替代方法,就是在某些浏览器中使用 focusinfocusout

4.结论

事件委托似乎是更好的方法,但是需要额外的处理。对此,我建议只在真正需要的时候使用实时绑定。有两种常见的情况需要事件委托:

动态元素

有一系列动态变化的DOM元素。

大的列表

当用实时绑定只需要一次绑定,而不是常规方法中的100次时,事件委托运行速度更快。这种方法在开始时更快,占用的内存也较少。

如果没有理由使用 live() ,那么就使用 bind() 。如果以后需要改为实时方式,切换也就是几秒钟的事情。

[1]http://en.wikipedia.org/wiki/Event-driven_programming

[2]http://docs.jquery.com/Events/jQuery.Event#event.data

[3]http://docs.jquery.com/Events/jQuery.Event

[4]http://docs.jquery.com/Events/live

[5]http://plugins.jquery.com/project/LiveQuery

[6]http://plugins.jquery.com/project/ElementReady

[7]http://docs.jquery.com/Events/jQuery.Event#event.stopPropagation.28.29

[8]http://docs.jquery.com/Events/jQuery.Event#event.stopImmediatePropagation.28.29

[9]http://www.w3.org/TR/DOM-Level-3-Events/

[10]http://docs.jquery.com/Events/jQuery.Event#event.isImmediatePropagationStopped.28.29

[11]http://docs.jquery.com/Events/jQuery.Event#event.target

[12]http://docs.jquery.com/Traversing/closest

[13]http://www.quirksmode.org/js/events_order.html

[14]http://en.wikipedia.org/wiki/DOM_events#Common.2FW3C_events

[15]http://www.quirksmode.org/js/events_order.html