事件是 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富应用开发》为主要学习资料。)


JingDing
2.5k 声望124 粉丝

新手请多多指教~