Javascript 事件机制
2017-10-31 本文已影响0人
ShawnRong
事件模型
DOM0级模型
在该模型中,事件不会传播,没有事件流的概念。这种模型兼容所有的浏览器。事件绑定监听函数有两种方式:
<!-- html 内联直接绑定 -->
<input type="button" onclick="fun()">
//通过js指定属性值
var btn = document.getElementById('.btn');
btn.onclick = fun;
//移除监听函数
btn.onclick = null;
IE事件模型
IE事件模型共有两个过程:
- 事件处理阶段,事件到达目标元素,触发目标元素的监听函数
- 事件冒泡阶段,事件从目标元素冒泡到document, 依次检查经过的节点是否绑定了事件监听函数,如果有则执行。
//添加监听
attachEvent(eventType, handler)
//移除监听
detachEvent(eventType, handler)
/*
* eventType指定事件类型(注意加on)
* handler是事件处理函数
**/
DOM2级模型
属于W3C标准模型,现代浏览器(除IE6-8之外的浏览器)都支持该模型。在该事件模型中,一次事件共有三个过程:
- 事件捕获阶段。事件从document一直向下传播到目标元素,依次检查经过的节点是否绑定了事件监听函数,如果有则执行。
- 事件处理阶段。事件到达目标元素,触发目标元素的监听函数。
- 事件冒泡阶段。事件从目标元素冒泡到document, 依次检查经过的节点是否绑定了事件监听函数,如果有则执行。
//绑定事件监听
addEventListener(eventType, handler, useCapture)
//移除事件监听
removeEventListener(eventType, handler, useCapture)
/**
* eventType指定事件类型(不要加on)
* handler是事件处理函数
* useCapture是一个boolean用于指定是否在捕获阶段进行处理,一般设置为false与IE浏览器保持一致。
*/
事件对象
DOM事件模型中的事件对象属性:
- type用于获取事件类型
- target获取事件目标
- stopPropagation()阻止事件冒泡
- preventDefault()阻止事件默认行为
IE事件模型中的事件对象常用属性:
- type用于获取事件类型
- srcElement获取事件目标
- cancelBubble阻止事件冒泡
- returnValue阻止事件默认行为
跨浏览器事件处理
var eventUtils={
// 添加句柄
addHandler:function(element,type,handler){
if(element.addEventListener){
element.addEventListener(type,handler,false);
}else if(element.attachEvent){
element.attachEvent('on'+type,handler);
}else{
element['on'+type]=handler;
}
},
// 删除句柄
removeHandler:function(element,type,handler){
if(element.removeEventListener){
element.removeEventListener(type,handler,false);
}else if(element.detachEvent){
element.detachEvent('on'+type,handler);
}else{
element['on'+type]=null;
}
},
//获取事件对象
//IE模型中event是一个全局唯一的对象绑定在window对象上
getEvent:function(event){
return event?event:window.event;
},
//获取类型
getType:function(event){
return event.type;
},
getElement:function(event){
return event.target || event.srcElement;
},
//阻止默认事件
preventDefault:function(event){
if(event.preventDefault){
event.preventDefault();
}else{
event.returnValue=false;
}
},
//阻止冒泡
stopPropagation:function(event){
if(event.stopPropagation){
event.stopPropagation();
}else{
event.cancelBubble=true;
}
}
}
事件代理
事件在冒泡过程中会上传到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件,这种方式被称为事件代理。
<div id="box">
<input type="button" value="按钮" id="btn">
<input type="button" value="按钮2" id="btn2">
<input type="button" value="按钮3" id="btn3">
</div>
var box = document.getElementById('box');
box.addEventListener('click', function(event) {
if (event.target.tagName.toLowerCase() === 'input') {
// some code
}
});
自定义事件
以创建以个三击事件为例
//创建一个事件
var event = new Event('threeclick', {"bubbles":true, "cancelable":false});
//为事件注册监听函数
target.addEventListener('threeclick', hello, false);
//触发函数
target.dispatchEvent(event);