前端之浏览器事件冒泡和事件捕获
2016-07-31 00:00
253 查看
摘要: DOM(文档对象模型)结构是一个树型结构,当一个HTML元素产生一个事件时,该事件会在元素结点与根结点之间的路径传播,路径所经过的结点都会收到该事件,这个传播过程可称为DOM事件流。
DOM(文档对象模型)结构是一个树型结构,当一个HTML元素产生一个事件时,该事件会在元素结点与根结点之间的路径传播,路径所经过的结点都会收到该事件,这个传播过程可称为DOM事件流。
事件流的传播方式可以分为两种:捕获型事件和冒泡型事件。
捕获型事件:最不具体的节点(document)最早接收到事件,而最具体的节点(目标节点)在最后接收到事件。事件捕获的用意在于事件到达预定目标之前捕获它。
冒泡型事件:事件开始时由最具体的节点(目标节点)接收,然后逐级向上传播到最不具体的节点(document)。
标准的事件传播分为三个阶段:(1)事件捕获阶段;(2)目标触发阶段;(3)事件冒泡阶段。
老版本的ie浏览器(ie9以下)只支持事件冒泡,不过现在新版本的浏览器都支持两种事件传播方式了。还有一些事件是不支持事件冒泡,如blur、focus,但是要经过捕获事件和目标触发阶段。
停止事件传递(stopPropagation()):停止事件的进一步传递(不仅可以停止事件冒泡,还可以停止事件捕获);老版本的ie不支持此方法,可以使用cancelBubble=true来停止事件冒泡。
阻止事件的默认行为(因为经常和事件流一起讲,所以放一起了,但并不属于事件流了):通常浏览器在事件传递并处理完后会执行与该事件关联的默认动作(如果存在这样的动作),如a标签点击之后会跳转到href对应的网址去,但是我们要阻止他跳转,就可以用preventDefault()方法,对于不支持的ie浏览器使用window.event.returnValue = false;
知道了事件流是什么了,也知道是怎么回事了,那么他有什么用呢?
答案当然是有用的了。
如果我们给目标元素注册了一个click事件,但是目标元素的父元素或者祖先元素也注册了一个click事件,而我们在触发目标元素的click事件的时候,其父元素或者祖先元素也触发了click事件。这显然并不是我们所希望的,我们只是想让被触发的元素相应click事件而已,那么这个时候你就需要阻止事件冒泡了(我们一般设置事件在事件冒泡时执行,以最大兼容浏览器)。如下:
当然这还不算什么,真正实用的是为多个子元素注册事件。如:现在有一个列表,列表里面的数据是会动态增删改的,如果我们需要对列表的每行数据都添加一个监听事件,那就意味着我们需要在每次新增加一行数据的时候都给新增的行注册事件,但是既然有事件冒泡机制,那我们就可以给列表的容器添加一个监听事件,然后再在容器里面做一些相应的处理。如:
DOM(文档对象模型)结构是一个树型结构,当一个HTML元素产生一个事件时,该事件会在元素结点与根结点之间的路径传播,路径所经过的结点都会收到该事件,这个传播过程可称为DOM事件流。
事件流的传播方式可以分为两种:捕获型事件和冒泡型事件。
捕获型事件:最不具体的节点(document)最早接收到事件,而最具体的节点(目标节点)在最后接收到事件。事件捕获的用意在于事件到达预定目标之前捕获它。
冒泡型事件:事件开始时由最具体的节点(目标节点)接收,然后逐级向上传播到最不具体的节点(document)。
标准的事件传播分为三个阶段:(1)事件捕获阶段;(2)目标触发阶段;(3)事件冒泡阶段。
老版本的ie浏览器(ie9以下)只支持事件冒泡,不过现在新版本的浏览器都支持两种事件传播方式了。还有一些事件是不支持事件冒泡,如blur、focus,但是要经过捕获事件和目标触发阶段。
停止事件传递(stopPropagation()):停止事件的进一步传递(不仅可以停止事件冒泡,还可以停止事件捕获);老版本的ie不支持此方法,可以使用cancelBubble=true来停止事件冒泡。
阻止事件的默认行为(因为经常和事件流一起讲,所以放一起了,但并不属于事件流了):通常浏览器在事件传递并处理完后会执行与该事件关联的默认动作(如果存在这样的动作),如a标签点击之后会跳转到href对应的网址去,但是我们要阻止他跳转,就可以用preventDefault()方法,对于不支持的ie浏览器使用window.event.returnValue = false;
知道了事件流是什么了,也知道是怎么回事了,那么他有什么用呢?
答案当然是有用的了。
如果我们给目标元素注册了一个click事件,但是目标元素的父元素或者祖先元素也注册了一个click事件,而我们在触发目标元素的click事件的时候,其父元素或者祖先元素也触发了click事件。这显然并不是我们所希望的,我们只是想让被触发的元素相应click事件而已,那么这个时候你就需要阻止事件冒泡了(我们一般设置事件在事件冒泡时执行,以最大兼容浏览器)。如下:
function stopPropagation(e) { e = e || window.event; if(e.stopPropagation) { //W3C阻止冒泡方法 e.stopPropagation(); }else { e.cancelBubble = true; //IE阻止冒泡方法 } }
当然这还不算什么,真正实用的是为多个子元素注册事件。如:现在有一个列表,列表里面的数据是会动态增删改的,如果我们需要对列表的每行数据都添加一个监听事件,那就意味着我们需要在每次新增加一行数据的时候都给新增的行注册事件,但是既然有事件冒泡机制,那我们就可以给列表的容器添加一个监听事件,然后再在容器里面做一些相应的处理。如:
function handler(e){ e=e || window.event; var el=e.target || e.srcElement; if(el.nodeName.toLowerCase()=='a'){ } }
相关文章推荐
- 浏览器中的事件捕获和冒泡
- 解析:浏览器事件冒泡及事件捕获
- 浏览器的事件捕获阶段和冒泡阶段笔记
- 01期:web浏览器事件传播机制(捕获和冒泡)
- 一个形象展示浏览器事件冒泡与捕获过程的demo
- 前端基本知识(一):W3C标准&&冒泡事件,捕获事件,W3C DOM对象模型,对比分析
- 用伪代码理解浏览器中的事件冒泡以及捕获
- 前端面试之事件捕获、时间冒泡总结
- 事件捕获和事件冒泡详解
- JS阻止事件冒泡兼容各浏览器
- js之事件冒泡和事件捕获
- 阻止事件冒泡和阻止浏览器默认行为
- 使用decj简化Web前端开发一:声明式Javascript动态加载和浏览器事件绑定
- javascript阻止事件冒泡和浏览器的默认行为
- 事件冒泡与事件捕获
- 事件冒泡和事件捕获
- javascript阻止事件冒泡和浏览器的默认行为
- 事件冒泡与捕获&事件托付
- 停止事件冒泡和阻止浏览器默认行为的脚本
- 事件捕获与事件冒泡