一想到“冒泡”这两个词会想到什么?想必然,那就是气泡自下而上的从水底往上生的场景,但是我们也知道,水在往上升的过程中,也会经历不同的高度。由此场景,那么想必然,冒泡的原理就可以很轻易的被理解啦。
我们知道,我们平时缩写的所看到的页面,都是由文档流即DOM树组成的,那么当我们在一个时间出发某个时间的时候,这个事件就会像这个气泡一样,从DOM树的底层,逐步向上传递,一直到DOM的根节点。当然,这事件冒泡的过程中,需要注意的一个点事,只有子元素和父级元素都有绑定了相同的事件,那么触发子组件的事件的时候,才会冒泡到父级组件中,这就是冒泡的基本原理。
不过我们也要清楚一点是,在不同浏览器中,冒泡是不一样的
注意:在JavaScript中 ,并非所有的事件都可以冒泡,像blur、unload、load等事件就不能冒泡
- <div class="father" @click="handleClickFather">
- 我是父元素
- <div class="son" @click="handleClickSon">我是子元素 div>
- div>
-
- <script>
- export default {
- data(){
- return {
- }
- },
- methods: {
- handleClickFather(){
- console.log('点击了father')
- },
- handleClickSon(){
- console.log('点击了son')
- }
- },
- }
- script>
- <style lang="css">
- .father {
- background:pink;
- height: 200px;
- width: 200px;
- padding: 20px;
- margin: 100px auto;
- }
- .son{
- width: 100px;
- height: 100px;
- background: #fff;
- line-height: 100px;
- text-align: center;
- cursor: pointer;
- margin-top: 20px;
- }
- style>
点击子元素时候的输出结果:
点击父元素时的输出结果:
以上例子我们可以看到,当我点击子元素时候,父元素绑定的点击事件也被触发了,那我们应该如何阻止这种事件的传递呢?
在W3C中,规定DOM标准通过调用event对象的stopPropagation()方法即可阻止冒泡型事件的进一步传递。
- <body>
- <div id="fater">
- 我是父元素
- <div id="son">我是子元素div>
- div>
- <script>
- var father = document.getElementById('father');
- var child = document.getElementById('child');
- father.addEventListener("click", function () {
- if(event && event.stopPropagation){
- event.stopPropagation() // 非IE浏览器
- }else{
- event.cancelBubble = true; //IE浏览器
- }
- console.log('我是父级元素')
- }, false)
- child.addEventListener("click", function () {
- if (event && event.stopPropagation) {
- event.stopPropagation() // 非IE浏览器
- } else {
- event.cancelBubble = true; //IE浏览器
- }
- console.log('我是子集元素')
- }, false)
- script>
- body>
场景:(类似于百度搜索功能)
实现:
说明:这里一共绑定了三个事件,①是给最外层父级元素绑定close事件,②是给下拉框绑定closeTop事件,③是给下拉框的子项绑定handleClickCompanyItem事件。作用解释如下:
由于这里的场景是点击下拉框子项的时候关闭下拉框,点击下拉框的时候保持打开,点击下拉框以外的元素关闭下拉框,所以我这里没有使用.stop来阻止冒泡事件。因此下面的事件就会各司其职。当点击子项的时候,由于父级和祖级的组件都绑定了相同类型的点击事件,因此会不断的向上冒泡,因此是这么一个过程:隐藏->显示->隐藏
假设这里没有点击子项关闭下拉框的需求,那么此时可以去掉子项的handleClickCompanyItem()事件,然后在下拉框事件上加上.stop的指令,这时候就会阻止事件向上冒泡。此时就是点击下拉框元素保持显示,点击除了下拉框意外的元素則會隐藏下拉框,因为已经阻止了事件向上冒泡,自然不会触发祖组件中的close事件。