“DOM2级事件”规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。下面这个图可以很形象的解释(理解捕获和冒泡必不可少的图)javascript
按照图咱们编写了代码去验证下,html
<div id="parent"> <div id="child"> child </div> </div> <script type="text/javascript"> var p = document.getElementById('parent'), c = document.getElementById('child'); p.addEventListener('click', function (e) { console.log('父节点捕获') }, true); c.addEventListener('click', function (e) { console.log('子节点捕获') }, true); c.addEventListener('click', function (e) { console.log('子节点冒泡'); }, false); p.addEventListener('click', function (e) { console.log('父节点冒泡') }, false); </script>
结果一目了然java
可是这里有个问题,也是原来阿里的面试题目,jquery
这个在参考小胡子哥的写js事件机制的博客中了解到,顺序是和绑定顺序有关系的,那咱们来试一下,面试
<div id="parent" style="height: 300px; background-color: #ccc;"> <div id="child"> child </div> <p>other child</p> </div> <script type="text/javascript"> var p = document.getElementById('parent'), c = document.getElementById('child'); p.addEventListener('click', function (e) { console.log('父节点冒泡') }, false); c.addEventListener('click', function (e) { console.log('子节点冒泡'); }, false); c.addEventListener('click', function (e) { console.log('子节点捕获') }, true); p.addEventListener('click', function (e) { console.log('父节点捕获') }, true); </script>
当点击1时dom
当点击2时ide
当点击3时spa
咱们发现1和3的状况下是先冒泡后捕获的,代码中我将冒泡的的绑定事件写到捕获前面了,形成了这样的效果,代理
那第二种为何顺序是先捕获后冒泡的呢,是由于事件目的地点 other child没有绑定事件。code
有捕获和冒泡就有相应的阻止,stopPropagation这个应该是阻止事件的下一步传播,stopImmediatePropagation这个方法能把绑定在这个元素上的事件都能阻止掉,能够了解下。
另附,易混淆的,
对“事件处理程序过多”问题的解决方案就是事件委托,事件委托利用了事件冒泡,只指定一个事件处理程序,就能管理这一类型的全部事件。
好比对ul下的li绑定事件,通常是遍历li,给每一个li绑定事件,这个有两个问题,1,若是是新加的li,咱们须要从新绑定。2,若是li有不少,那占用内存会不少。
那咱们这个时候就能够用事件委托了,委托在词典中解释,将本身的事务嘱托他人代为处理。那就是事件我不放到要处理的dom上面,也就是利用冒泡的原理,将事件绑定到父级上面。再按照每一个触发事件的event对象找到target,说到这,又要说兼容问题了,w3c的标准下的,event.target便可,IE的确是event.srcElement。到这我想你们应该会想到一个神器,jQuery了,对的,他里面的绑定事件都是兼容的,都是封装好的,那他又是怎么处理的呢,好吧,要去解读源码了。