归纳DOM事件中各种阻止方法

34次阅读

共计 3090 个字符,预计需要花费 8 分钟才能阅读完成。

前言
在复习事件这块的时候,发现了一个问题,网上很多文章对事件阻止这块解析的并不全面,并且有些文章也有错误之处,于是想自己总结一下,也方便自己的复习。
知识预热
事件冒泡和捕获
在看本篇文章之前,需要了解事件的冒泡和捕获,这里简单介绍下事件冒泡:即事件开始时由最具体的元素 (文档中嵌套层数最深的那个点) 接收,然后逐级向上传播到较为不具体的节点(文档),可理解为:
由 div->body->html->document

事件捕获:不太具体的节点应该更早接收到事件,而最具体的节点应该最后接收到事件,可理解为:
由 document->html->body->div
DOM2 级规定的事件流包括三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段
dom 事件绑定处理
与此同时,我们还需要了解 dom 事件绑定处理的几种方式
①、HTML 事件处理(在 dom 元素中嵌入)
<button onclick=”fn()”></button>
缺点:1、this 指向 window 2、HTML 与 JS 紧密耦合,改动代码麻烦
②、DOM0 级事件处理(获取 dom 元素直接绑定)
document.getElementById(‘btn’).onclick = fn
优点:1、this 指向 dom 元素 2、不存在浏览器兼容问题
③、DOM2 级事件处理(事件监听)
document.getElementById(‘btn’).addEventListener(‘click’,fn)
优点:this 指向 dom 元素 缺点:1、需要对 IE8 及以下进行兼容 document.getElementById(‘btn’).attachEvent(‘click’,fn)由于 IE8 及以下只支持事件冒泡,所以通过 attachEvent 都会被添加到冒泡阶段 IE 中的 attachEvent 中的 this 总是指向全局对象 Window

方法详解
stopPropagation()
event.stopPropagation()

作用:终止事件在传播过程的捕获、目标处理或起泡阶段进一步传播兼容:在 IE<9 的浏览器上使用 event.cancelBubble = true

preventDefault()
event.preventDefault()

作用:取消事件的默认动作备注:只有 cancelable 属性为 true 的事件,才可以使用 preventDefault()兼容:在 IE 浏览器中通过 e.returnValue = false

return false
return false
return 在函数中有三个作用:1、用来返回一些值,当然也可以不写返回值 2、终止函数的执行,就是说在 return 之后的代码都不会执行 3、在 DOM0 级事件中,可以像 event.preventDefault() 取消默认事件,但是在 DOM2 级则不行
stopImmediatePropagation()
event.stopImmediatePropagation()

作用:阻止事件冒泡并且阻止相同事件的其他侦听器被调用。备注:阻止相同事件的其他侦听器被调用指的是:如果有多个相同类型事件的事件监听函数绑定到同一个元素,当该类型的事件触发时,它们会按照被添加的顺序执行。如果其中某个监听函数执行了 event.stopImmediatePropagation() 方法,则当前元素剩下的监听函数将不会被执行。

验证方法
接下来我们来验证一下,创建一个 html 文件, 写入如下代码
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<title> 阻止默认事件和冒泡 </title>
<style>
div{width: 300px; height: 300px; background-color: pink;}
</style>
<script>
// 接下来要写的代码
</script>
</head>
<body>
</body>
</html>
本次验证所监听的事件是
oncontextmenu

oncontextmenu 事件在元素中用户右击鼠标时触发并打开上下文菜单
由于一个个验证比较麻烦,这里把所有的代码都写出来
第一个是针对 DOM0 级事件的 JS 代码
document.querySelector(“div”).oncontextmenu = function(event){
event.stopImmediatePropagation(); // 可以阻止事件传播
event.stopPropagation(); // 可以阻止事件传播
event.preventDefault(); // 可以阻止默认事件
return false; // 可以阻止默认事件
console.log(“dom0-div”);
};
document.oncontextmenu = function(event){
event.preventDefault(); // 可以阻止默认事件
return false; // 可以阻止默认事件
console.log(“dom0-document”);
};
第二个是针对 DOM2 级事件的 JS 代码
document.querySelector(“div”).addEventListener(‘contextmenu’, function(event){
event.stopImmediatePropagation(); // 可以阻止事件传播
event.stopPropagation(); // 可以阻止事件传播
event.preventDefault(); // 可以阻止默认事件
// return false; // 不能阻止默认事件
console.log(“dom2-div”)
});
document.addEventListener(‘contextmenu’, function(event){
event.preventDefault(); // 可以阻止默认事件
// return false; // 不能阻止默认事件
console.log(“dom2-document”)
});
验证是否可以成功阻止事件传播:右击 div 元素,控制台查看是否有 dom0-document 或者 dom2-document;如果没有,则阻止成功,如果有,则阻止失败。验证是否可以成功阻止默认事件:右击鼠标,看是否会出现菜单栏;如果没有,则阻止成功,如果有,则阻止失败。
这里重点提一下 stopImmediatePropagation(),这个方法除了阻止事件冒泡还可以阻止相同事件的其他侦听器被调用。看以下例子:
const div = document.querySelector(‘div’);

document.addEventListener(“click”, (event) => {
console.log(“document 事件 ”);
// event.stopImmediatePropagation()具有事件传播的效果,所以这里不会执行
});

div.addEventListener(“click”, (event) => {
console.log(“ 第 1 个事件 ”);
});

div.addEventListener(“click”, (event) => {
console.log(“ 第 2 个事件 ”);
event.stopImmediatePropagation();
});

div.addEventListener(“click”, (event) => {
console.log(“ 第 3 个事件 ”);
// event.stopImmediatePropagation()具有阻止相同事件的其他侦听器被调用的效果,所以这里不会执行
});

正文完
 0