阻止事件冒泡和事件捕获的方法及vue事件修饰符的使用
一、事件冒泡和事件捕获
1. 是什么
事件冒泡(Event Bubbling)和事件捕获(Event Capturing)是JavaScript事件处理机制的两个重要概念。它们决定了事件在DOM树中传播的方式。
2. 事件传播机制
事件传播是指当一个事件发生时,事件在DOM树中的传播过程。事件传播分为三个阶段,如下:
事件捕获阶段(Capturing Phase)、目标阶段(Target Phase)、 事件冒泡阶段(Bubbling Phase)
2.1 事件捕获阶段(Capturing Phase)
事件捕获阶段是事件从最顶层的元素(通常是window对象)开始,向事件目标元素传播的过程。在这个阶段,事件会沿着DOM树从上到下传播。
2.2 目标阶段(Target Phase)
目标阶段是事件到达事件目标元素的阶段。在这个阶段,事件会被事件目标元素处理。
2.3 事件冒泡阶段(Bubbling Phase)
事件冒泡阶段是事件从事件目标元素向最顶层元素传播的过程。在这个阶段,事件会沿着DOM树从下到上传播。
3. 事件冒泡(Event Bubbling)
3.1 定义
事件冒泡是指事件从目标元素开始,沿着DOM树向上逐层传播,直到最顶层的元素(通常是window对象)。
<!DOCTYPE html>
<html>
<head>
<title>Event Bubbling Example</title>
</head>
<body>
<div id="parent">
Parent
<button id="child">Child</button>
</div>
<script>
document.getElementById('parent').addEventListener('click', function() {
console.log('Parent clicked');
});
document.getElementById('child').addEventListener('click', function() {
console.log('Child clicked');
});
</script>
</body>
</html>
在上述示例中,点击button元素会触发两次点击事件,首先是button元素自身,然后是它的父元素div,即事件冒泡。
3.2 阻止事件冒泡
可以使用event.stopPropagation()方法来阻止事件冒泡。
document.getElementById('child').addEventListener('click', function(event) {
event.stopPropagation();
console.log('Child clicked');
});
在上述示例中,调用event.stopPropagation()方法后,点击button元素只会触发button元素自身的点击事件,而不会冒泡到父元素div。
4. 事件捕获(Event Capturing)
4.1 定义
事件捕获是指事件从最顶层的元素开始,沿着DOM树向下逐层传播,直到事件目标元素。
<!DOCTYPE html>
<html>
<head>
<title>Event Capturing Example</title>
</head>
<body>
<div id="parent">
Parent
<button id="child">Child</button>
</div>
<script>
document.getElementById('parent').addEventListener('click', function() {
console.log('Parent clicked');
}, true);
document.getElementById('child').addEventListener('click', function() {
console.log('Child clicked');
});
</script>
</body>
</html>
在上述示例中,设置事件监听器的第三个参数为true时,表示在捕获阶段处理事件。点击button元素时,首先触发父元素div的点击事件,然后是button元素自身的点击事件。
4.2 阻止事件捕获
可以使用event.stopPropagation()方法来阻止事件捕获。
document.getElementById('parent').addEventListener('click', function(event) {
event.stopPropagation();
console.log('Parent clicked');
}, true);
在上述示例中,调用event.stopPropagation()方法后,点击button元素时,只会触发父元素div的点击事件,而不会捕获到button元素的点击事件。
5. 阻止默认行为
除了阻止事件传播,有时还需要阻止事件的默认行为。例如,点击链接时阻止跳转。
调用event.preventDefault()方法可以阻止链接的默认跳转行为。
<!DOCTYPE html>
<html>
<head>
<title>Prevent Default Example</title>
</head>
<body>
<a href="https://www.example.com" id="link">Click me</a>
<script>
document.getElementById('link').addEventListener('click', function(event) {
event.preventDefault();
console.log('Link clicked but default action prevented');
});
</script>
</body>
</html>
在上述示例中,调用event.preventDefault()方法可以阻止链接的默认跳转行为。
事件冒泡是事件从目标元素向上传播,而事件捕获是事件从最顶层元素向下传播。
通过使用event.stopPropagation()方法,可以阻止事件传播(事件冒泡和事件捕获),通过event.preventDefault()方法,可以阻止事件的默认行为。
二、事件修饰符
1、是什么
Vue.js 为 v-on 提供了事件修饰符来处理 DOM 事件细节,如:event.preventDefault() 或 event.stopPropagation()。
Vue.js 通过由点 . 表示的指令后缀来调用修饰符。
.stop - 阻止冒泡
.prevent - 阻止默认事件
.capture - 阻止捕获
.self - 只监听触发该元素的事件
.once - 只触发一次
<!-- 阻止单击事件冒泡 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件侦听器时使用事件捕获模式 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当事件在该元素本身(而不是子元素)触发时触发回调 -->
<div v-on:click.self="doThat">...</div>
<!-- click 事件只能点击一次,2.1.4版本新增 -->
<a v-on:click.once="doThis"></a>
2、使用事件修饰符 .prevent
注释了// e.preventDefault(),但是通过@click.prevent="eventStyle"的方式设置了禁用默认事件.
点击了这么多下还在原来的网页.
<template>
<h3>事件修饰符</h3>
<a @click.prevent="eventStyle" href="www.baidu.com">跳转</a>
</template>
<script>
export default {
data() {
return {};
},
methods: {
eventStyle(e) {
// e.preventDefault(); //禁用控件本身默认的事件,比如说我们a标签的跳转到百度事件会被禁用
console.log("点击了");
},
},
};
</script>
3、使用了.stop 禁用了冒泡
只触发了p不会触发父节点div的事件
不加打印点击了p,点击了div;加了只打印点击了p
<template>
<h3>事件修饰符</h3>
<div @click="clickDiv">
<p @click.stop="clickP">点我先触发p还是div呢?</p>
</div>
</template>
<script>
export default {
data() {
return {};
},
methods: {
clickDiv() {
console.log("点击了div");
},
clickP() {
console.log("点击了p");
},
},
};
</script>
4、使用事件修饰符 .self
只有点击"div的内容"才会触发,也就是只有点击了div本身自己才能触发事件,不受到冒泡影响.哪怕p没有使用.stop也不会通过p触发div
<template>
<div @click.self="clickDiv">
div的内容
<p @click="clickP">点我先触发p还是div呢?</p>
</div>
</template>
<script>
export default {
data() {
return {};
},
methods: {
clickDiv() {
console.log("点击了div");
},
clickP() {
console.log("点击了p");
},
},
};
</script>
参考:https://blog.csdn.net/JHXL_/article/details/140258096
https://blog.csdn.net/u011027547/article/details/136688049?spm=1001.2014.3001.5502