10.2.6 事件传播
当事件目标是Window对象或其他一些单独对象(比如XMLHttpRequest)时,浏览器会简单的通过调用对象上适当的处理程序响应事件。
在调用在目标元素上注册的事件处理函数后,大部分事件会“冒泡”到DOM树根。
发生在文档元素上的大部分事件都会冒泡,但有些例外,比如focus、blur和scroll事件。文档元素上的load事件会冒泡,但它会在Document对象上停止冒泡而不会传播到Window对象。只有当整个文档都加载完毕时才会触发window对象的load事件。
当事件目标是文档或文档元素时,它会在不同的DOM节点之间传播(propagation)。
分为三个阶段:
- 捕获阶段(capture phase):从window对象传导到目标对象。(window--document--....--目标对象)
- 目标阶段(target phase):目标对象本身的事件处理程序调用。
- 冒泡阶段(bubbling phase):从目标对象传导回window对象。(目标对象--父元素--....--document--window)
事件代理(事件委托)
基于事件会在冒泡阶段向上传播到父节点,我们可以将子节点的监听事件定义在父节点上,由父节点的监听函数统一处理多个子元素的事件。这种方法叫做事件的代理(delegation)。
document.getElementById('div').addEventListener('click', function(e) {
var target = e.target;
if(target.getAttribute('id').toLowerCase() == 'item') {
alert(1);
}
});
如果使用事件代理,以后插入的新节点仍然可以监听的到。
如果使用JQuery,我们要为新增节点添加事件,除了在新增事件后添加事件外,还可以用下面的代码:
$(document).on('click','div',function(){})
这种方式其实就是使用了事件代理。
10.2.7 事件取消
用属性注册的世界处理程序的返回值能用于取消事件的浏览器默认操作。在支持addEventListener()的浏览器中,也能通过调用事件对象的preventDefault()方法取消事件的默认操作。
在IE9之前的IE中,可以通过设置事件对象的returnValue属性为false来达到同样的效果。
function cancelHandler(event){
var event = event || window.event;
if(event.preventDefault) {event.preventDefault();} //标准
if(event.returnValue) { event.returnValue = false;} // IE
return false; //用于处理使用对象属性注册的处理程序
}
Event对象提供了一个属性defaultPrevented,返回一个布尔值,默认false,表示该事件是否调用过preventDefault方法。
取消事件传播
在支持addEventListener()的浏览器中,可以调用事件对象的一个stopPropagation()方法以阻止事件的继续传播。
e.stopPropagation()
//IE
e.cancelBubble = true;
在Event对象上还有一个方法stopImmediatePropagation(),阻止同一个事件的其他监听函数被调用。也就是说,如果同一个节点对于同一个事件指定了多个监听函数,这些函数会根据添加的顺序依次调用。只要其中有一个监听函数调用了stopImmediatePropagation方法,其他的监听函数就不会再执行了。
e.addEventListener('click',function(event){
event.stopImmediatePropagation();
});
e.addEventListener('click',function(event){
//不会触发
});
著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
原文: http://ghmagical.com/article/page/id/nXCnaSLsuyWd © ghmagical.com