我试图找出事件冒泡的路径。例如,我有一个像
的标记 <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 - &gt; div2.3 - &gt; div2 - &gt;容器。有没有办法只在容器上放一个处理程序? (请不要Jquery)
我找到了一个event.path数组。这是什么东西,但是找不到它的详细信息。它是否跨浏览器?实现这一目标的正确方法是什么?
答案 0 :(得分:20)
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);
答案 1 :(得分:15)
event.path
|| event.composedPath()
event.path
来自whatwg:
如果事件的目标属性值参与树,则让事件路径成为树序中所有祖先的静态有序列表,否则让事件路径成为空列表。
通过polymer project documentation和an HTML5Rocks article中的备注拒绝/取消覆盖,这似乎只是event
界面的“扩展名通过Web Component Shadow DOM 曝光。
标准仅在这方面(显然),虽然现在还没有很多文档可用(我们必须写它; - )
自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>
答案 2 :(得分:1)
我在听文档上的事件时有一个类似的要求,想知道事件是否起源于特定的div。我通过添加并稍后检查event.target上的特定类名称来处理它。
var div1 = document.getElementById('div1');
var div2 = document.getElementById('div2');
document.addEventListener('click', function(e) {
if (e.target.classList.contains('via-div1')) {
alert('Event came through div1');
} else if (e.target.classList.contains('via-div2')) {
alert('Event came through div2');
} else {
alert('Event came from outside the divs');
}
});
div1.addEventListener('click', function(e) {
e.target.classList.add('via-div1');
});
div2.addEventListener('click', function(e) {
e.target.classList.add('via-div2');
});
<div id="div1" style="background: #8bc34a"><span>div 1</span></div>
<div id="div2" style="background: #00bcd4">
<span>div 2</span>
<div id="div2-1"><span>div 2-1</span></div>
<button id="btn2-2">button 2-2</button>
</div>
答案 3 :(得分:0)
现在有一个名为.ToList
的小型GitHub项目/ NPM模块充当了polyfill。在这里查看:
答案 4 :(得分:0)
让我们假设我们要在HTML table标记内找到事件路径。
<tabe id="tab">
.
.
.
</table>
以下JavaScript代码将在每个事件之后返回事件的元素。
window.onload = function(){
var tab = document.getElementById('tab');
tab.onclick = function(event) {
var target = getTargetElement(event);
console.log(target);
};
}
function getTargetElement(e) {
e = e || window.event;
return e.target || e.srcElement;
}