事件是 JavaScript 应用程序的核心,是所有内容的驱动。尽管后来W3C 对此做了标准化,但 IE 仍然坚持使用与 W3C 不兼容的事件模型,直到 IE9 才遵循标准。有很多诸如 jQuery 和 Prototye 的类库很好地处理了兼容性问题,对外提供了统一的 API 来实现事件。
监听事件
绑定事件监听的函数是addEventListener()
,有 3 个参数:type
(比如click),listener
(比如callback)及seCapture
。使用前两个参数可以给一个 DOM 元素绑定一个函数,当特定的事件(比如点击)被触发时执行这个函数:
var button = document.getElementById("createButton");
button.addEventListener("click", function(){ /* ... */ }, false);
可以使用removeEventListener()
来移除事件监听,参数和传入addEventListener()
的一样。如果监听的函数是匿名函数,没有任何引用指向它,在不销毁这个元素的前提下,这个监听是无法被移除的:
var div = document.getElementById("div");
var listener = function(event) { /* ... */ };
div.addEventListener("click", listener, false);
div.removeEventListener("click", listener, false);
带入listener
函数的第 1 个参数是event
对象,通过event
象可以得到事件的相关信息,比如时间戳、坐标和事件宿主元素(target)。它同样包含很多方法来停止事件冒泡和阻止事件的默认行为。
不同的浏览器对事件类型的支持有些差异,但所有现代浏览器都支持这些事件:
- click
- dblclick
- mousemove
- mouseover
- mouseout
- focus
- blur
- change (表单输入框特有)
- submit (表单特有)
事件顺序
如果一个节点和它的一个父节点都绑定了相同事件类型的回调,当事件触发时哪个回调会先执行?
浏览器不同有不同的默认执行顺序,分为两种:
- 事件捕捉(capturing),从顶层的父节点开始触发事件,从外到内传播。
- 事件冒泡(bubbling),从最内层的节点开始触发事件,逐级冒泡直到顶层节点,从内向外传播。
W3C将对这两种事件模型的支持都加入标准规范之中。根据W3C型,事件首先被目标元素所捕捉,然后向上冒泡。
可以自行选择要注册的事件处理程序的调用类型,捕捉或冒泡,通过给addEventListener()
传入第3个参数useCapture
来设置。如果addEventListener()
的最后一个参数是true
,事件处理程序以捕捉模式触发;如果是false
,事件处理程序以冒泡模式触发:
// 给最后一个参数传入false,来设置事件冒泡
button.addEventListener("click", function(){ /* ... */ }, false);
大多数情况下是使用冒泡模式,如果对此不太确定,可以给addEventListener()`的最后一个参数传入false。
取消事件冒泡
当事件冒泡时,可以通过stopPropagation()
数来终止冒泡,这个函数是event
对象中的方法。比如这段代码,任何父节点的事件回调都不会触发:
button.addEventListener("click", function(e){
e.stopPropagation();
/* ... */
}, false);
jQuery 还支持stopImmediatePropagation()
函数,用来阻止后续所有的事件触发——哪怕这些事件是注册在同一个节点元素上的。
阻止浏览器的默认行为
浏览器给事件赋予了默认行为。比如,点击一个链接时,浏览器的默认行为是载入新页面,当点击一个复选框时,浏览器会将其选中(或取消选中)。在事件传播阶段(之后)会触发这些默认行为,在任何一个事件处理程序中都可以阻止默认行为。可以通过调用event
对象的preventDefault()
函数来阻止默认行为,也可以通过在回调中返回false
来实现同样的效果:
bform.addEventListener("submit", function(e){
/* ... */
return confirm("Are you super sure?");
}, false);
如果调用confirm()
返回false
(用户点击了对话框的取消按钮),这个事件回调函数就返回false
,这样就会取消事件,阻止表单的提交。
(公开记录学习JS MVC,不知道能坚持多久= =。以《基于MVC的JavaScript web富应用开发》为主要学习资料。)