一、事件传播
(1)事件的三个阶段:事件捕获—>处于目标—>事件冒泡
(2)事件捕获:当触发dom事件时,浏览器会从根节点开始从外到内进行事件传播,即点击了子元素,如果父元素通过事件捕获机制注册了对应的事件的话,会先触发父元素绑定的事件。
(3)事件冒泡:与捕获相反,事件冒泡顺序是从内到外进行事件传播,直到根节点。
二、事件绑定的方法
(1)基本事件模型——被所有浏览器支持——通过dom元素的事件属性绑定方法
//可以这么写
<button onclick="func()"></button>
//也可以这么写
doucument.getElementById('btn').onclick=function(){...}
//解除绑定
doucument.getElementById('btn').onclick=null
(2)DOM2事件模型——被除了低版本ie(ie8-)以外的主流浏览器支持——addEventListener
使用addEventListener和removeEventListener绑定和解除事件绑定
语法:
dom.addEventListener(eventName, functionName, useCapture)
dom.removeEventListener(eventName, functionName)
其中,useCapture默认为false,表示在冒泡阶段触发方法,true表示在捕获阶段触发方法,
//事件绑定
dom.addEventListener('click', function DoSomething(e) {
...
}, false)
//解除事件绑定
dom.removeEventListener('click', DoSomething)
备注:新的addEventListener语法把第三个参数变成了一个option对象,如下
dom.addEventListener(type, listener, {
capture: false,
passive: false,
once: false
})
passive
: Boolean
,设置为true时,表示 listener
永远不会调用 preventDefault()。如果 listener 仍然调用了这个函数,客户端将会忽略它并抛出一个控制台警告。
once
: Boolean
,表示 listener在添加之后最多只调用一次。如果是
true,
listener
会在其被调用之后自动移除。
(3)IE事件模型(ie10-)
使用attachEvent和detachEvent进行事件绑定和解除事件绑定
语法
dom.attachEvent(event,listener)
dom.detachEvent(event,listener)
//进行事件绑定
dom.attachEvent('click', function DoSomething(e) {
...
})
//解除事件绑定
dom.detachEvent('click', DoSomething)
三、事件代理(事件冒泡的应用)
比如给一个ul里面的多个li绑定同一个点击事件,普通的做法需要给每一个li都绑定一次。
缺点:(1)代码中躲不开循环绑定的步骤,代码繁琐
(2)添加到页面上的事件处理程序数量大,占用内存多,影响网页性能。
事件代理则是利用事件冒泡原理,由于在子节点上面触发的点击事件会冒泡给父节点,给父节点绑定事件,则可以处理所有子节点上的点击事件。
事件代理的优点:
(1)代码简洁,管理的事件处理程序变少,优化了性能
(2)新增加的li元素,不需要再次绑定事件
如何在事件代理中,获取触发事件的节点——使用event.target(ie8-不兼容),event.srcElement
四、阻止事件捕获、冒泡
//w3c 可以取消捕获和冒泡
e.stopPropagation();
//ie 可以取消冒泡
e.cancleBubble = true;
//兼容的取消冒泡的写法
function cancelBubble(e) {
if(e && e.stopPropagation) {
e.stopPropagation();
}else {
window.event.cancelBubble = true;
}
}
五、阻止浏览器默认行为(扩展)
//w3c
e.preventDefault()
//ie的方法1
return false;
//ie的方法2
event.returnValue = false;
六、eventPhrase
event对象的一个属性,通过eventPhrase可以判断事件的不同阶段