我试图找出事件冒泡的路径。例如,我有一个标记
<div id="container" onclick="func">
<div id="div1"></div>
<div id="div2">
<div id="div2.1"></div>
<span id="span2.2"></span>
<div id="div2.3">
<button id="btn2.3.1"></button>
</div>
</div>
</div>
现在如果单击btn2.3.1,我希望看到事件已经冒出的整个路径,其中btn2.3.1 - > div2.3 - > div2 - > container。有没有办法只在容器上放一个处理程序? (请不要Jquery)
我找到了一个event.path数组。这是什么东西,但是找不到很多关于它的细节。它是否跨浏览器?实现这一目标的正确方法是什么?
event.path
|| event.composedPath()
event.path
来自whatwg:
如果事件的目标属性值参与树,则让事件路径成为树中所有祖先的静态有序列表,否则让事件路径为空列表。
在polymer project documentation和an HTML5Rocks article中的音符消息/未被覆盖,这似乎是仅通过event
Shadow DOM暴露的“Web Component界面的扩展”。
它只是在这方面(显然)是标准的,虽然现在还没有很多文档可用(我们必须写它;-)
自2016年1月23日起,所有浏览器均未公开(默认情况下)。
但基本上:
var red = document.getElementById( "red" ),
green = document.getElementById( "green" ),
msg = document.querySelector( "p" );
red.addEventListener( "click", function( evt ) {
msg.textContent = "'" + evt.target.id + "' got poked, and 'green' was" +
// access to the event path
( ~evt.path.indexOf( green ) ? "" : "n't" ) +
" in the path.";
}, false );
div { display: inline-block; min-width: 20px; min-height: 20px;
padding: 20px 40px 20px 20px; text-align: center; cursor: pointer; }
#red { background: red; }
#green { background: green; }
#blue { background: blue; }
p { font: 20px Consolas; }
<!DOCTYPE html><html><body>
<div id="red">
<div id="green">
<div id="blue"></div>
</div>
</div>
<p></p>
</body></html>
换句话说:path
是一种Array
形式的家谱。
另一个question about the use of path
是answered with a suggestion to use composedPath
...
event.composedPath()
自从我上次编辑这个答案以来,MDN开发了(双关语)some documentation about event.composedPath()
。
截至2019年3月8日,根据MDN,Edge或IE不支持此功能。
注意事项照常应用:
如果阴影根是在其
ShadowRoot.mode
关闭的情况下创建的,则[将在其上调用侦听器的对象数组]不包括阴影树中的节点。
使用composedPath()
,上面的相同片段看起来像这样工作:
var red = document.getElementById( "red" ),
green = document.getElementById( "green" ),
msg = document.querySelector( "p" );
red.addEventListener( "click", function( evt ) {
msg.textContent = "'" + evt.target.id + "' got poked, and 'green' was" +
// access to the event path
( ~evt.composedPath().indexOf( green ) ? "" : "n't" ) +
" in the path.";
}, false );
div { display: inline-block; min-width: 20px; min-height: 20px;
padding: 20px 40px 20px 20px; text-align: center; cursor: pointer; }
#red { background: red; }
#green { background: green; }
#blue { background: blue; }
p { font: 20px Consolas; }
<!DOCTYPE html><html><body>
<div id="red">
<div id="green">
<div id="blue"></div>
</div>
</div>
<p></p>
</body></html>
function handleClicks(e) {
var path = [];
var node = e.target;
while(node != document.body) {
path.push(node);
node = node.parentNode;
}
console.log(path);
}
document.body.addEventListener('click', handleClicks);
现在有一个名为event-propagation-path
的小型GitHub项目/ NPM模块,它充当了polyfill。看看这里: