JavaScript事件模型有以下三种模型。
1.原始事件模型(DOM0级事件模型)
这是一种被所有浏览器都支持的事件模型(优点),没有事件流,事件一旦发生将马上进行处理,有两种方式可以实现原始事件:
(1)在html代码中直接指定属性值:<button id="demo" type="button" οnclick="doSomeTing()" />
(2)在js代码中为 document.getElementsById("demo").onclick = doSomeTing()
移除监听函数只要设置为null:
1 | btn.onclick = null; |
缺点:1)逻辑与显示没有分离;2)相同事件的监听函数只能绑定一个(即同类型函数只能注册一个),后注册绑定的会覆盖掉前面的,如:a.onclick = func1; a.onclick = func2;将只会执行func2中的内容;3)无法通过事件的冒泡、委托等机制完成更多事情。
因为这些缺点,虽然原始事件类型兼容所有浏览器,但仍不推荐使用。
2.DOM2事件模型
此模型是W3C制定的标准模型,现代浏览器(IE6~8除外)都已经遵循这个规范。W3C制定的事件模型中,一次事件的发生包含三个过程。
事件捕获(capturing):当某个元素触发某个事件(如onclick),顶层对象document就会发出一个事件流,随着DOM树的节点向目标元素节点流去,直到到达事件真正发生的目标元素。在这个过程中,事件相应的监听函数是不会被触发的。
事件目标(target):当到达目标元素之后,执行目标元素该事件相应的处理函数。如果没有绑定监听函数,那就不执行。
事件冒泡(bubbling):从目标元素开始,往顶层元素传播。途中如果有节点绑定了相应的事件处理函数,这些函数都会被一次触发。
所有的事件类型都会经历事件捕获但是只有部分事件会经历事件冒泡阶段,例如submit事件就不会被冒泡。
事件的传播是可以阻止的:
• 在W3c中,使用stopPropagation()方法。在捕获的过程中stopPropagation()方法后,后面的冒泡过程就不会发生了。
• 在IE下设置cancelBubble = true;
标准的事件监听器该如何绑定:
addEventListener("eventType","handler","true/false");其中eventType指事件类型(事件名称),注意不要加‘on’前缀,与IE下不同。第二个参数是处理函数,第三个指定是否在捕获阶段进行处理,一般设置为false与IE浏览器保持一致。(通常可理解为,true代表捕获事件,false代表冒泡事件。)监听器的解除也类似:removeEventListner("eventType","handler","true/false");
3.IE事件模型
IE不把该对象传入事件处理函数,由于在任意时刻只会存在一个事件,所以IE把它作为全局对象window的一个属性,一旦函数执行结束,便被置为null了。
IE事件模型共有两个过程:
- 事件处理阶段(target phase)。事件到达目标元素, 触发目标元素的监听函数。
- 事件冒泡阶段(bubbling phase)。事件从目标元素冒泡到document, 依次检查经过的节点是否绑定了事件监听函数,如果有则执行。
事件绑定监听函数的方式如下:
1 | attachEvent(eventType, handler) |
事件移除监听函数的方式如下:
1 | detachEvent(eventType, handler) |
参数说明:
- eventType指定事件类型(注意要加 on )
- handler是事件处理函数
Example:
1 2 3 | var btn = document.getElementById('.btn'); btn.attachEvent(‘onclick’, showMessage); btn.detachEvent(‘onclick’, showMessage); |
IE的事件模型已经可以解决原始模型的三个缺点,但其自己的缺点就是兼容性,只有IE系列浏览器才可以这样写。
由于事件模型的差异以及Event对象的不同,为了达到兼容各个浏览器的目的,我们可以增加一个Event Wrapper, 它对各个浏览器应当提供一致的事件操作接口。