<A>
小一点(而且更安全,因为找不到
[HTML, BODY, DIV, DIV, P, SPAN, A]
):target
您可以尝试以下操作:
var a = document.getElementById("target");
var els = [];
while (a) {
els.unshift(a);
a = a.parentNode;
}
var nodes = [];
var element = document.getElementById('yourelement');
nodes.push(element);
while(element.parentNode) {
nodes.unshift(element.parentNode);
element = element.parentNode;
}
... $ 0是您的元素。
此方法的好处是它可以用作表达式的值。
[...(function*(e){do { yield e; } while (e = e.parentNode);})($0)]
您可以沿着
[...(function*(e){while (e = e.parentNode) { yield e; }})($0)]
S的链条行走,直到达到虚假价值,并在您走时附加到一个数组:
const getParents = el => {
for (var parents = []; el; el = el.parentNode) {
parents.push(el);
}
return parents;
};
const el = document.querySelector("b");
console.log(getParents(el).reverse().map(e => e.nodeName));
<div><p><span><b>Foo</b></span></div>
纯粹用于呈现和非必需品。注意,这种方法意味着您将以文档元素作为链中的最后一个元素结束。如果您不想要那个,则可以将
e.nodeName
添加到循环停止条件中。
&& el !== document
是在就地的,因此不需要额外的分配。正如其他一些答案所建议的那样,在循环中是二次的,可能会损害罕见的深层树木的可扩展性,以换取优雅的可忽略的增益。
其他替代方案(基于
这):
reverse()
我认为,如果您经常使用此功能,那么在大多数情况下,这很可能是长期运行
。 t会更具性能的原因是因为它最初检查以查看可能遇到的祖先的深度。另外,该功能并非每次调用时都会创建一个新数组,而是有效地重复使用相同的数组,并切成薄片,在某些浏览器中非常优化。但是,由于我知道没有真正有效的方法来检查最大深度,因此我对查询效率低下的检查。
unshift
上述函数的浏览器兼容性是它将在边缘工作,但在IE中不起作用。如果您需要IE支持,那么您将需要一个
for(var e = document.getElementById("target"),p = [];e && e !== document;e = e.parentNode)
p.push(e);
polyfill。
您可以在MDN文章中阅读的阴影根周围的一些微妙之处,但是您的代码很可能不会具有阴影根,因此它要简单得多,并且只会将一个数组从事件的目标返回到根节点。 请参见Https://developer.mozilla.org/en-us/docs/web/api/event/composedpath
document
window
<html>
<body>
<div>
<button onclick="onClick">Click me</button>
</div>
</body>
</html>
知道更多