js事件模型
JavaScript事件使得网页具备互动和交互性,对js事件模型的了解可以帮助我们更加深入了解其中的原理,便于开发工作,在目前各种浏览器中,JavaScript的事件模型主要分为三种,DOM0级事件模型(原始事件模型)、DOM2事件模型、IE事件模型。
DOM0级事件模型
DOM0级事件模型是一种被所有浏览器都支持的事件模型,对于原始事件而言,没有事件流,事件一旦发生将马上进行处理。以点击事件为例,有两种常见的方法绑定事件。
(1)在html代码中直接指定属性值,如下代码
<button id="demo" type="button" onclick="fun()" />
(2)在js代码中,如下代码
<p id = 'click'>click me</p>
<script>
document.getElementById('click').onclick = function(event){
alert(event.target);
}
</script>
这种事件模型就是直接在dom对象上注册事件名称,在对应标签上注册了一个onclick事件,在这个事件函数内部输出点击的目标,而解除事件则将null复制给事件函数,如下代码。
document.getElementById('click'_).onclick = null;
但对于原始事件模型,一个dom对象只能注册一个同类型的函数,注册多个同类型的函数就会发生覆盖,之前注册的函数就会无效。
var click = document.getElementById('click');
click.onclick = function(){
alert('you click the first function');
};
click.onclick = function(){
alert('you click the second function')
}
以上代码执行后点击只会输出you click the second function,表示前面所注册的函数被覆盖了。
DOM0级事件模型(原始事件模型)
优点:所有浏览器都兼容;
缺点:1)逻辑与显示没有分离;2)相同事件的监听函数只能绑定一个,后绑定的会覆盖掉前面的3)无法通过事件的冒泡、委托等机制完成更多事情。
DOM2事件模型
DOM2事件模型也被称作标准模型一次事件的发生包含三个过程:事件捕获阶段、事件目标阶段、事件冒泡阶段。
事件捕获阶段:当某个元素触发某个事件,顶层对象document就会发出一个事件流,随着DOM树的节点向目标元素节点流去,直到到达事件真正发生的目标元素。
事件目标阶段:当到达目标元素之后,执行目标元素该事件相应的处理函数。如果没有绑定监听函数,那就不执行。
事件冒泡阶段:目标元素开始,往顶层元素传播。
事件绑定函数方法:addEventListener(事件类型, 事件处理函数, true/false)
第三个参数true表示捕获、false表示冒泡,默认为false,为true时捕获阶段依次检查经过的节点是否绑定了事件监听函数,如果有则执行。为false时冒泡依次检查经过的节点是否绑定了事件监听函数,如果有则执行。
事件移除监听函数的方式:removeEventListener(事件类型, 事件处理函数, true/false)
具体模型图如下
IE事件模型
IE事件模型共有两个过程:
事件处理阶段:事件到达目标元素, 触发目标元素的监听函数。
事件冒泡阶段:事件从目标元素冒泡到document, 依次检查经过的节点是否绑定了事件监听函数,如果有则执行。
绑定监听函数的方法是:attachEvent( 事件的类型,事件处理函数),注意事件类型要加’on’。解除事件监听器的方法是 detachEvent(事件的类型,事件处理函数)。
为了兼容ie,通常绑定事件兼容的写法如下:
var demo = document.getElementById('demo');
if(demo.attachEvent){
demo.attachEvent('onclick',fun);
}else{
demo.addEventListener('click',fun,false);
}
在开发过程中如不需要触发捕获或冒泡机制的话可以阻止捕获或冒泡,代码如下
//(1) 阻止默认事件
function(e){
if(e && e.preventDefault){
e.preventDefault();
}else{ //IE
window.event.returnValue = false;
}
}
//(2) 阻止冒泡事件
function(e){
if(e && e.stopPropagation){
e.stopPropagation();
}else{ //IE
window.event.cancleBubble = true;
}
}