事件触发的三个阶段:
- window 往事件触发处传播,遇到注册的捕获事件会触发
- 传播到事件触发处时触发注册的事件
- 从事件触发处往 window 传播,遇到注册的冒泡事件会触发
注册事件(事件绑定)
- 直接获取元素绑定
element.onclick = function () {
// ...
}
优点:简单稳定,确保在不同浏览器中操作一致,this关键字引用的是当前元素。
缺点:只会在事件冒泡中运行,一个元素一次只能绑定一个事件处理函数,新绑定的事件处理函数会覆盖旧的事件处理函数;
- 直接在元素里面使用事件属性
- W3C方法:
element.addEventListener('click', function(e){
// ...
}, false)
优点:该方法同时支持事件处理的捕获和冒泡阶段;事件阶段取决于 addEventListener 最后的参数设置;false(冒泡)或 true (捕获);在事件处理函数内部,this关键字引用当前元素;事件对象总是可以通过处理函数的第一个参数(e)捕获;可以为同一个元素绑定你所希望的多个事件,并且不会覆盖先前绑定的事件
缺点:IE不支持,必须使用IE的 attachEvent函数替代。
element.attachEvent('onclick', function(){
// ...
})
缺点:仅支持事件捕获的冒泡阶段;事件监听函数内的this关键字指向了 window 对象,事件对象仅存在于window.event 参数中;事件必须以ontype的形式命名,如onclick 非 click
如果我们只希望事件只触发在目标上,可以使用 stopPropagation
来阻止事件的进一步传播。通常我们认为stopPropagation 是用来阻止事件冒泡的,其实该函数也可以阻止捕获事件。stopImmediatePropagation 同样也能实现阻止事件,但是还能阻止该事件目标执行别的注册事件。
事件委托
在JavaScript中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能。
首先,每个函数都是对象,都会占用内存;内存中的对象越多,性能就越差
事件代理
如果一个节点中的子节点是动态生成的,子节点需要注册事件应该注册在父节点上
let body = document.querySelector('body')
body.addEventListener('click', (event) => {
console.log(event.target)
})
优点:节省内存,并且 不需要给子节点注销事件
解除事件
element.removeEventListener('click', function(e){
// ...
}, false)
// IE
element.detachEvent('onclick', function(){
// ...
})
阻止事件传播
stopPropagation() 方法阻止事件的传播
IE9之前 设置 对象 cancelBubble 为 true
阻止事件的默认行为
e.preventDefault()
IE9之前 设置对象的 returnValue 为 false
function cancelHandler(event){
var event=event||window.event;//兼容IE
//取消事件相关的默认行为
if(event.preventDefault) //标准技术
event.preventDefault();
if(event.returnValue) //兼容IE9之前的IE
event.returnValue=false;
return false; //用于处理使用对象属性注册的处理程序
}
网友评论