事件模型
一个事件发生后,会在子元素和父元素之间传播。
这种传播分成三个阶段。
window→documen→...→目标节点
第一阶段:捕获阶段,从window对象传导到目标节点
第二阶段:目标阶段,事件在目标节点上触发
第三阶段:冒泡阶段,从目标节点传回window对象
IE678的事件模型只有冒泡阶段。
![点击并拖拽以移动](https://i-blog.csdnimg.cn/blog_migrate/85882dfd59eaa5fdca94449de8c21304.png)
总结:
"DOM2级事件"规定事件流的三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。首先发生的是事件捕获,为截获事件提供了机会;然后是实际的目标接收到事件;最后一个阶段是冒泡阶段,可以在这个阶段对事件作出响应,
即:事件捕获->事件处理->事件冒泡
阻止事件冒泡
event.stopPropagation()
stopImmediatePropagation方法阻止同一个事件的其他监听函数被调用,不管监听函数定义在当前节点还是其他节点。也就是说,该方法阻止事件的传播,比Event.stopPropagation()更彻底。
event.stopImmediatePropagation()
event.cancelBubble()
IE阻止事件冒泡
![点击并拖拽以移动](https://i-blog.csdnimg.cn/blog_migrate/85882dfd59eaa5fdca94449de8c21304.png)
事件委托
事件委托原理:事件委托是利用事件的冒泡原理来实现的,何为事件冒泡呢?就是事件从最深的节点开始,然后逐步向上传播事件,举个例子:页面上有这么一个节点树,div>ul>li;比如给最里面的li加一个click点击事件,那么这个事件就会一层一层的往外执行,执行顺序li>ul>div,有这样一个机制,那么我们给最外面的div加点击事件,那么里面的ul,li做点击事件的时候,都会冒泡到最外层的div上,所以都会触发,这就是事件委托,委托它们父级代为执行事件。
![点击并拖拽以移动](https://i-blog.csdnimg.cn/blog_migrate/85882dfd59eaa5fdca94449de8c21304.png)
案例:
<ul id="ul"> <li>aa</li> <li>bb</li> <li>cc</li> </ul> <script> window.onload = function(){ var oUl = document.getElementById("ul"); oUl.onclick = function(ev){ var ev = ev || window.event; var target = ev.target || ev.srcElement; if(target.nodeName.toLowerCase() == 'li'){ console.log(target.innerHTML); } } } </scropt>
![点击并拖拽以移动](https://i-blog.csdnimg.cn/blog_migrate/85882dfd59eaa5fdca94449de8c21304.png)
事件捕获->事件处理->事件冒泡,父级ul做事件处理,当li被点击时,由于冒泡原理,事件就会冒泡到ul上,因为ul上有点击事件,所以事件就会触发,当然,这里当点击ul的时候,也是会触发的,怎么只有点击li才会触发呢.
Event对象提供了一个属性叫target,可以返回事件的目标节点,我们成为事件源,也就是说,target就可以表示为当前的事件操作的dom,但是不是真正操作dom,当然,这个是有兼容性的,标准浏览器用ev.target,IE浏览器用event.srcElement,此时只是获取了当前节点的位置,并不知道是什么节点名称,这里我们用nodeName来获取具体是什么标签名
![点击并拖拽以移动](https://i-blog.csdnimg.cn/blog_migrate/85882dfd59eaa5fdca94449de8c21304.png)
事件委托优点:
1. 只在内存中开辟了一块空间,节省资源同时减少了dom操作,提高性能
2. 对于新添加的元素也会有之前的事件
![点击并拖拽以移动](https://i-blog.csdnimg.cn/blog_migrate/85882dfd59eaa5fdca94449de8c21304.png)
总结:什么样的事件可以用事件委托,什么样的事件不可以用呢?
适合用事件委托的事件:click,mousedown,mouseup,keydown,keyup,keypress。
不适合的就有很多了,举个例子,mousemove,mouseout,每次都要计算它的位置,非常不好把控,在不如说focus,blur之类的,本身就没用冒泡的特性,自然就不能用事件委托了。
![点击并拖拽以移动](https://i-blog.csdnimg.cn/blog_migrate/85882dfd59eaa5fdca94449de8c21304.png)