1事件冒泡

在目标元素获得机会处理事件后,事件模型检查目标元素的父元素,看是否为同类型事件建立了处理程序。如果是,则也调用父元素的处理程序。在这之后,再检查其父元素,然后父元素,然后父元素。。。持续不停直到DOM树的顶部。因为事件处理向上传播就像香槟酒杯里冒起的气泡,所以这个过程称为事件冒泡。

这是一种强大的能力,因为允许把处理程序建立在任何一级的元素上,从而处理在后代元素上发生的事件。在设计编程时要很好的掌握这种技巧,需要时可以把子事件可以放在父元素来执行。但是,如果不想让事件传播出去,怎么停止传播呢?防止事件向上传播,对于标准浏览器,调用event的stopPropagation()方法可以中止事件祖先层次传播,对于IE9以下浏览器,则将event实例中名为cancelBubble的属性设置为true.

2事件捕获

事件首先从DOM树的根向下传播到目标元素称为事件捕获,也称捕获阶段。

在DOM第2级事件模型下,建立事件是通过一个元素方法,每个元素都定义名为addEventListener()的方法(监听器),用户把处理程序附加到元素上,addEventListener(eventType,listener,usrCapture).

useCapture为true时建立捕获型处理程序,也就是向下传播中触发事件,为false是冒泡型处理程序,向上冒泡中触发事件。

因为有父, 子节点同在, 因为有监听事件和浏览器默认动作之分. 使用 JavaScript 时为了达到预期效果经常需要阻止事件和动作执行. 一般我们会用到三种方法, 分别是 stopPropagation(), preventDefault()return false. 它们之间有什么区别

术语

监听事件, 在在节点上能被监听的页面操作. 如: select 节点的 change 事件, a 节点的 click 事件.
浏览器默认动作, 指特定页面元素上带有的功能. 如: 点击 a 链接节点的跳转动作, 表单提交动作.

stopPropagation()

因为事件可以在各层级的节点中传递, 不管是冒泡还是捕获, 有时我们希望事件在特定节点执行完之后不再传递, 可以使用事件对象的 stopPropagation() 方法.

假设页面上存在一个浮动弹出层, 显示在最前面, 当点击弹出层以外页面区域时, 隐藏弹出层. 为了做到这样的效果, 我们会监听 documentElement 的 click 事件, 一旦事件被触发即隐藏弹出层. 但是...

这显然存在问题. 当用户点击弹出层时, 我们不希望它隐藏掉. 但因为事件的冒泡传递, documentElement 的 click 事件也会被触发. 这个时候, 我们可以监听弹出层的 click 事件, 并使用 stopPropagation() 方法阻止冒泡. 请参考下面的代码.

// 在弹出对话框上点击时, 不进行任何页面操作, 并阻止冒泡
document.getElementById('dialog').onclick = function(ev) { ev.stopPropagation(); };   // 在 documentElement 节点上监听到点击事件时, 隐藏对话框 document.documentElement.onclick = function(ev) { document.getElementById('dialog').style.display = 'none'; };

stopPropagation() 相当好用, 可是 IE8 及以前版本都不支持. IE 的事件对象包含特有的属性 cancelBubble, 只要将它赋值为 false 即可阻止事件继续. 如:

// 在弹出对话框上点击时, 不进行任何页面操作, 并阻止冒泡
document.getElementById('dialog').onclick = function(ev) { ev.cancelBubble = false; };

preventDefault()

一个带事件监听的链接代码如下:

<a href="http://w3c.org" onclick="alert('JavaScript Click Event');">点击链接</a>

点击该链接, 显示对话框后跳转页面. 由此可知, 除了执行监听事件还会触发浏览器默认动作; 执行监听事件在前, 触发浏览器默认动作在后.

这里有个经典示例, 我们希望点击链接在新窗口打开页面, 但不希望当前页面跳转. 这个时候可以使用 preventDefault() 阻止后面将要执行的浏览器默认动作.

<a id="link" href="http://w3c.org">W3C 首页链接</a>   <script> // 在新窗口, 打开页面 document.getElementById('link').onclick = function(ev) { // 阻止浏览器默认动作 (页面跳转) ev.preventDefault(); // 在新窗口打开页面 window.open(this.href); }; </script>

return false

退出执行, return false 之后的所有触发事件和动作都不会被执行. 有时候 return false 可以用来替代 stopPropagation()preventDefault(), 比如我们上面新窗口打开链接的例子, 如:

<a id="link" href="http://w3c.org">W3C 首页链接</a>   <script> // 在新窗口, 打开页面 document.getElementById('link').onclick = function(ev) { // 在新窗口打开页面 window.open(this.href); // 退出执行 (在监听事件之后执行的浏览器默认动作将不会被执行) return false; }; </script>

有人认为 return false = stopPropagation() + preventDefault(), 其实是错的. return false 不但阻止事件, 还可以返回对象, 跳出循环等... 方便地一刀切而不够灵活, 滥用易出错.

retrun 有以下三种,区别为:

retrun true; 返回正确的处理结果。

return false;分会错误的处理结果,终止处理。

return;把控制权返回给页面。

在做网页时,经常会对按钮等添加事件,比如表单提交,有时候发现,明明点了一次提交按钮,数据库却多添加了一条甚至多条记录,造成原因可能是一次连接触发了多次按钮,还有可能是事件发生了冒泡.前一种方法可以把按钮点击后设置disabled属性为true即为不可用状态即可.后一种可以用Event的stopPropagation()方法来阻止.

比如下面例子,一个div,在div中包含一标签a,div大小比a 大,我们给div一个事件,这是点击div和a都会触发这个事件:

<!DOCTYPE HTML>
<html>
<head>
<style type="text/css">div{width:100px;height:100px;background:#0094ff;}a{width:80px;height:80px;display:block;background:#b6ff00;}
</style><script src="jquery-1.11.3.min.js"></script></head>
<body><div><a href="javascript:void(0)">点击我</a></div><script type="text/javascript">$("div").click(function (e) {alert("div");})$("a").click(function (e) {alert("a");})</script>
</body>
</html>

 

其实一般我们想要的结果是,点击a时不触发div事件:

<!DOCTYPE HTML>
<html>
<head>
<style type="text/css">div{width:100px;height:100px;background:#0094ff;}a{width:80px;height:80px;display:block;background:#b6ff00;}
</style><script src="jquery-1.11.3.min.js"></script></head>
<body><div><a href="javascript:void(0)">点击我</a></div><script type="text/javascript">$("div").click(function (e) {// if (this != e.target)//     return false;alert("div");})$("a").click(function (e) {       e.stopPropagation();alert("a");})</script>
</body>
</html>

 上面用 if(this != e.target)  return false;也是阻止冒泡的一种方法,好好想想,这里很有意思,方法很多,想要用好它们还需深入理解,这样才会在使用中不易出错.

1.this和event.target的区别:

js中事件是会冒泡的,所以this是可以变化的,但event.target不会变化,它永远是直接接受事件的目标DOM元素;

2.this和event.target都是dom对象,如果要使用jquey中的方法可以将他们转换为jquery对象:$(this)和$(event.target);

上面还可以用下面方法 解决传播问题

    <script type="text/javascript"> $("div").click(function (e) {  alert("div"); }) $("a").click(function (e) { alert("a");        return false; //阻止冒泡,结束,后面不再执行, }) </script>

既要防止事件传播,也要停止默认行为,只需要用return false;就可以完全实现。

转载于:https://www.cnblogs.com/lunawzh/p/4907390.html

js 事件阻止传播方法,准确定位事件源相关推荐

  1. js事件-阻止默认操作

    默认操作 具体指的是什么呢?看如下实例: (1)把单击事件处理程序注册到一个锚元素,而不是一个外层的<div>上,那么就要面对另外一个问题:当用户单击链接时,浏览器会加载一个新页面. (2 ...

  2. 重新认识vue之事件阻止冒泡

    冒泡的表现 近期用vue做了一个需求,大概是同一个区域,点击不同位置有不同的响应函数,还有个总的响应函数,好吧,如下图所示: 他们的DOM结构如下: <div v-for="(item ...

  3. js 事件流的事件冒泡和事件捕获与阻止事件传播

    为了方便引入事件流的概念,我们先来说说什么是事件. 事件就是用户或浏览器自身执行的某种动作.换句话说,我们在浏览网页或者 APP 时,通常会在设备上产生很多交互性的操作,例如点击.选择.滚动屏幕.键盘 ...

  4. JS中如何阻止事件的传播

    一个事件发生后,会在子元素和父元素之间传播(propagation).这种传播分成三个阶段.这种三阶段的传播模型,使得同一个事件会在多个节点上触发. 第一阶段:从window对象传导到目标节点(上层传 ...

  5. 快速了解4种阻止事件冒泡的方法(原生js阻止,vue中使用修饰符阻止)

    阻止事件冒泡的方法 前端结构 <div id="app"><div class="father-box" @click="click ...

  6. JS中阻止冒泡事件的三种方法

    冒泡事件:比如说鼠标点击了一个按钮,同样的事件将会在那个元素的所有祖先元素中被触发.这一过程被称为事件冒泡. <div class="box"><button c ...

  7. js 事件冒泡、阻止事件冒泡

    JS事件流其中一种是冒泡事件,当一个元素被触发一个事件时,该目标元素的事件会优先被执行,然后向外传播到每个祖先元素,恰如水里的一个泡泡似的,从产生就一直往上浮,到在水平面时,它才消失.在这个过程中,如 ...

  8. js事件技巧方法整合

    window.resizeTo(800,600); //js设置浏览器窗口尺寸 window.open (function(){resizeTo(640,480);//设置浏览器窗口尺寸moveTo( ...

  9. js关于子元素不触发父元素事件的若干方法

    2019独角兽企业重金招聘Python工程师标准>>> 方法一:event.cancelBubble=true; /* 最好用,js通用,event.cancelBubble=tru ...

最新文章

  1. 股市币市:数据分析与交易所公告(20190226)
  2. 是起点,而非终点——评《程序员的思维修炼》
  3. 系统性能检测工具之lsof
  4. 5.2 FIR滤波器的卷积(脉冲响应、频率响应,幅频响应,暂态-搞不清楚的有救了啊)
  5. 重写 隐藏 java_Java中方法的重写与成员变量的隐藏
  6. 485 九针头_三代德玛莎针头 九针头 十三针头 9针头 13针头 原装进口
  7. RabbitMQ 下载、安装、配置、验证_rpm版本(Linux环境)
  8. DBASK问答集萃第二期
  9. usercontroller.java,springboot controller 参数绑定
  10. 几个大厂及 RCE漏洞二三事
  11. html5 valid,html5中valid、invalid、required的定义
  12. 计算机网络nos是什么意思,什么是网络操作系统(NOS)
  13. python plc fx5u_三菱PLC FX5U CPU模块专用指令的处理内容
  14. 使用vue做图片的闪光效果
  15. 软考分类精讲-知识产权与标准化
  16. 《基于AI+大数据的医疗大健康最佳实践》---- AI 赋能临床试验受试者招募助力企业药物研发
  17. 大物计算机在线使用,计算机怎么发展为电脑的
  18. linux网卡聚合是什么意思,linux网卡聚合
  19. 编写程序,找出用户输入的一串数的最大数,程序需要提示用户一个一个地输入数,当用户输入0或负数时,程序显示出已输入的最大负整数:
  20. oracle怎样修改口令,修改Oracle数据库sys口令

热门文章

  1. Electerm for Mac(终端模拟器/免费ssh客户端)
  2. 【Kali】手把手配置网络方法
  3. python 连接数据库 慢_python数据库mysql第二天
  4. 社会化分享功能的实现
  5. 个人创业如何赚钱?现在做什么生意赚钱?
  6. Flink Mailbox模型
  7. action mailbox
  8. 高版本CUDA 在算力低的显卡上不执行核函数如no kernel image is available for execution on the device
  9. Lenovo Y480 Ubuntu 12.04 x64 安装NVIDIA GT 650M 驱动
  10. Google三驾马车之GFS