六十二、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
参考文章
- https://mp.weixin.qq.com/s/ahPNIzPuZRAOsL6LxR6GwA
- https://mp.weixin.qq.com/s/pp4OxkNRAY5PmpVJ1U-XOg
- 慕课网Vue2.5->2.6->3.0 开发去哪儿网App 从零基础入门到实战项目开发
后言
据说,放张小姐姐照片可以提高阅读量,图是来源学校的2020级新生。
文章来源: maoli.blog.csdn.net,作者:刘润森!,版权归原作者所有,如需转载,请联系作者。
原文链接:maoli.blog.csdn.net/article/details/109142279
- 点赞
- 收藏
- 关注作者
评论(0)