替代chrome中的Event.path

本博客 hjy-xh,转载请申明出处

Event.path和Event.composedPath

在开发过程时,有时需要获取事件冒泡/捕获过程的所有元素,在不同的浏览器中,获取的方法可能不一样

chrome作为常用的浏览器,可以通过event.path属性来获取,示例如下:

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
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>event.path测试</title>
</head>

<body>
<p>组织/部门</p>
<ul class="department">
<li id="dev">研发组</li>
<li id="administrative">行政组</li>
<li>公关组</li>
</ul>

</body>

<script type="text/javascript">
const target = document.getElementById("dev")
target.onclick = function(evt) {
const path = evt.path;
console.log('研发组点击事件的path:', path)
}
</script>

</html>

Chrome(版本:108.0.5359.124)操作结果:

Firefox(版本:108.0.1)操作结果:

该属性返回事件路径,但并不是一个标准属性,不过在 chrome 浏览器中存在,而Firefox不存在

Event.path 取不到值时就取 Event.composedPath

Event.composedPath的兼容性如下:

在2021年12月份,chrome官方团队发布issue,将要移除event.path

现有项目如何处理

现有项目和依赖的第三方库/包都有可能受到影响,在这种情况下可以添加polyfill作为成本较小的解决方案:

1
2
3
4
5
6
7
if (!Event.prototype.path) {
Object.defineProperty(Event.prototype, "path", {
get() {
return this.composedPath();
},
});
}

其它

如何支持IE?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
(function(e, d, w) {
if(!e.composedPath) {
e.composedPath = function() {
if (this.path) {
return this.path;
}
var target = this.target;

this.path = [];
while (target.parentNode !== null) {
this.path.push(target);
target = target.parentNode;
}
this.path.push(d, w);
return this.path;
}
}
})(Event.prototype, document, window);