背景介绍
- 事件,是文档或浏览器窗口中发生的一些特定的交互瞬间。
- 事件流,描述的是页面中接受事件的顺序
事件冒泡:
事件冒泡是由IE开发团队提出来的,即事件开始时由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播,
最后冒泡到window对象。
事件捕获
事件捕获是由Netscape Communicator团队提出来的,是先由最上一级的节点先接收事件,然后向下传播到具体的节点。当用户点击了元素,采用事件捕获,则click事件将按照document—>html—>body—>div 的顺序进行传播。点击div,将先输出“body”,再输出“div”
DOM事件流
"DOM2级事件”规定的事件流包含三个阶段:
(1)事件捕获阶段:在事件冒泡的模型中,捕获阶段不会响应任何事件;
(2)处于目标阶段:目标阶段就是指事件响应到触发事件的最底层元素上;
(3)事件冒泡阶段:冒泡阶段就是事件的触发响应会从最底层目标一层层地向外到最外层(根节点),事件代理即是利用事件冒泡的机制把里层所需要响应的事件绑定到外层;
首先发生的是事件捕获,然后是实际的目标接收到事件,最后阶段是冒泡阶段。以上面为例,单击元素将按照下图触发事件:
1589550584-5c0fdf0682f48_articlex.png若在div和body上都定义了click事件,如下:
1.png
点击div,将先输出“event catch”,再输出“div”,最后输出“event bubble”。
总结:
先按由上往下的顺序执行事件捕获的执行程序,再执行目标元素的执行程序,最后按由下往上的顺序执行冒泡事件。
阻止事件冒泡和捕获
-
IE8以及以前可以通过 window.event.cancelBubble=true阻止事件的继续传播;IE9+/FF/Chrome通过event.stopPropagation()阻止事件的继续传播。
2.png
当点击outC的时候,之后打印出capture-->target,不会打印出bubble。因为当事件传播到outC上的处理函数时,通过stopPropagation阻止了事件的继续传播,所以不会继续传播到冒泡阶段。
事件委托
委托的优点:
- 减少内存消耗
如果给每个列表项一一都绑定一个函数,那对于内存消耗是非常大的
2.动态绑定事件
比如列表项就几个,我们给每个列表项都绑定了事件;
在很多时候,我们需要通过 AJAX 或者用户操作动态的增加或者去除列表项元素,那么在每一次改变的时候都需要重新给新增的元素绑定事件,给即将删去的元素解绑事件;
如果用了事件委托就没有这种麻烦了,因为事件是绑定在父层的,和目标元素的增减是没有关系的,执行到目标元素是在真正响应执行事件函数的过程中去匹配的;
所以使用事件在动态绑定事件的情况下是可以减少很多重复工作的。
if (!Element.prototype.matches) {
Element.prototype.matches =
Element.prototype.matchesSelector ||
Element.prototype.mozMatchesSelector ||
Element.prototype.msMatchesSelector ||
Element.prototype.oMatchesSelector ||
Element.prototype.webkitMatchesSelector ||
function(s) {
var matches = (this.document || this.ownerDocument).querySelectorAll(s),
i = matches.length;
while (--i >= 0 && matches.item(i) !== this) {}
return i > -1;
};
}
document.getElementById('list').addEventListener('click', function (e) {
// 兼容性处理
var event = e || window.event;
var target = event.target || event.srcElement;// currentTarget:表示此事件绑定的元素target:通俗理解为表示触发一系列事件的源头
if (target.matches('li.class-1')) {
console.log('the content is: ', target.innerHTML);
}
});
网友评论