六十二、Js中的冒泡和捕获点击事件和Vue组件绑定原生事件

举报
毛利 发表于 2021/07/15 01:47:19 2021/07/15
【摘要】 2020/10/18 、 周日、今天又是奋斗的一天。 @Author:Runsen @Date:2020/10/18 写在前面:我是「Runsen」,热爱技术、热爱开源、热爱编程。技术是开源的、知识是共享的。大四弃算法转前端,需要每天的日积月累, 每天都要加油!!! 文章目录 Js中的冒泡点击事件禁用事件冒泡机制Js中事件捕获Vue组件绑定原生事件子组件...
2020/10/18 、 周日、今天又是奋斗的一天。

@Author:Runsen

@Date:2020/10/18

写在前面:我是「Runsen」,热爱技术、热爱开源、热爱编程。技术是开源的、知识是共享的。大四弃算法转前端,需要每天的日积月累, 每天都要加油!!!

Js中的冒泡点击事件

记得刚学JS时讲的事件冒泡:“鱼在水中吐泡泡,是在鱼所在的深水区逐渐上升到水面”。就如这个例子一样,下面我总结一下我所理解的冒泡和捕获。

现在我都忘得一干二净。

<html>
<head>
  <title>js事件冒泡测试</title>
</head>
<body onclick='alert("body")'>
  <div id='content' onclick='alert("content")'> <div id='div' onclick='alert("div");'> <ul onclick='alert("ul");'> <li onclick='alert("li");'>test</li> </ul> </div>
  </div>
</body>
</html>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

因此在事件冒泡的概念下在;li元素上发生click事件的顺序应该是li -> ul-> div -> content -> body

事件冒泡是自上而下的触发事件,也就是先执行我们触发的按钮所绑定的事件,执行完后,接着执行按钮父元素所绑定的事件。

禁用事件冒泡机制

解决方法是禁用事件冒泡机制。w3c的方法是e.stopPropagation(),IE则是使用e.cancelBubble = true

<head>
  <title>js事件冒泡测试</title>
  <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
</head>
<body onclick='alert("body")'>
  <div id='content' onclick='alert("content")'> <div id='div' onclick='alert("div");'> <ul onclick='alert("ul");'> <li onclick='alert("li");'>test</li> </ul> </div>
  </div>
  <script> $("li").click(function (e) { // e.stopPropagation(); //ie e.cancelBubble = true if(e.stopPropagation){ e.stopPropagation(); }else{ window.event.cancelBubble = true; } });
  </script>
</body>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

Js中事件捕获

Js提出另一种事件流名为事件捕获(event capturing)。与事件冒泡相反,事件会从最外层开始发生,直到最具体的元素。

因此在事件捕获的概念下在p元素上发生click事件的顺序应该是document -> html -> body -> div -> p

后来 w3c 采用折中的方式,平息了战火,制定了统一的标准——先捕获再冒泡

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>事件捕获和冒泡</title>
  <style type="text/css">
  #child{ background: red; width:50px; height:50px;
  }
  #father{ width:100px; height:100px; background:green;
  }
  #grandparent{ width:150px; height:150px; background:black; margin:100px auto 0;
  }  </style>
</head>
<body>
  <div id='grandparent'> <div id='father'> <div id='child'></div> </div>
  </div>
</body>
<script type="text/javascript"> var grandparent = document.getElementById("grandparent")
  var parent = document.getElementById("father")
  var child = document.getElementById('child')
  var html = document.getElementsByTagName("html")[0]
  var body = document.body
  grandparent.addEventListener("click",function () { console.log("I am capturing grandparent");
  },true);
  grandparent.addEventListener("click",function () { console.log("I am grandparent");
  },false); parent.addEventListener("click",function() { console.log("I am parent");
  },false);
  parent.addEventListener("click",function() { console.log("I am capturing parent");
  },true); child.addEventListener("click",function() { console.log("I am capturing child");
  },true);
  child.addEventListener("click",function() { console.log("I am child");
  },false); body.addEventListener("click",function() { console.log("I am body");
  },false);
  body.addEventListener("click",function() { console.log("I am capturing body");
  },true);
  html.addEventListener("click",function() { console.log("I am capturing html");
  },true);
  html.addEventListener("click",function() { console.log("I am html");
  },false);
  document.addEventListener("click",function() { console.log("I am capturing document");
  },true);
  document.addEventListener("click",function() { console.log("I am document");
  },false);
  window.addEventListener("click",function() { console.log("I am window");
  },false);
  window.addEventListener("click",function() { console.log("I am capturing window");
  },true);</script>
</html>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80

事件冒泡和事件捕获都是描述事件触发时序问题的术语,也就是事件流。(简单说就是描述在页面中点击一个按钮时,是先执行这个节点的事件还是先执行这个节点父节点的事件的顺序。)

Vue组件绑定原生事件

下面是Vue组件中内容,了解一下,给组件绑定原生事件是个什么样子

下面点击不会弹出HandleClick,具体代码如下

<body>
  <!-- 这里点击child是不会弹出HandleClick,需要对template绑定原始事件 -->
  <div id="app"> <child @click="HandleClick"></child>
  </div>
  <script> Vue.component("child",{ template:"<div>child</div>" }) var vm = new Vue({ el: "#app", methods: { HandleClick:function(){ alert("HandleClick") } }, })
  </script>
</body>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

因为点击的是子组件,在子组件中没有绑定HandleClick事件。

子组件触发自定义事件$emit

对此解决的方法是自定义事件『子组件触发自定义事件$emit』,需要在template绑定点击事件

<body>
  <div id="app"> <child @click="HandleClick"></child>
  </div>
  <script> Vue.component("child",{ // 需要在template绑定点击事件 template:"<div @click='HandleChildClick'>child</div>", methods:{ HandleChildClick:function(){ alert('HandleChildClick') // 子组件触发自定义事件$emit  注意emit括号里是字符串 this.$emit("click") } } }) var vm = new Vue({ el:"#app", methods: { HandleClick:function(){ alert('HandleClick'); } }, })
  </script>
</body>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

父组件的原生事件@click.native(快速)

但是对于上面的代码,使用子组件触发自定义事件$emit有些麻烦,因此还有一种做法就是
原生事件『子组件的原生事件、父组件的原生事件@click.native』

<body>
  <!-- 父组件的原生事件@click.native(快速)监听的不是自定义事件,而是原生事件 -->
  <div id="app"> <child @click.native="HandleClick"></child>
  </div>
  <script> Vue.component("child",{ template:"<div>child</div>" }) var vm = new Vue({ el: "#app", methods: { HandleClick:function(){ alert("HandleClick") } }, })
  </script>
</body>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

参考文章

后言

据说,放张小姐姐照片可以提高阅读量,图是来源学校的2020级新生。

文章来源: maoli.blog.csdn.net,作者:刘润森!,版权归原作者所有,如需转载,请联系作者。

原文链接:maoli.blog.csdn.net/article/details/109142279

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。