我的意思是他们的一系列.这是从顶级HTML到目标元素的链,包括元素本身.
例如,对于元素<A>,它将是:
[HTML, BODY, DIV, DIV, P, SPAN, A]
Run Code Online (Sandbox Code Playgroud)
Way*_*ett 39
稍短(更安全,因为target可能找不到):
var a = document.getElementById("target");
var els = [];
while (a) {
els.unshift(a);
a = a.parentNode;
}
Run Code Online (Sandbox Code Playgroud)
tec*_*bar 19
您可以尝试以下方式:
var nodes = [];
var element = document.getElementById('yourelement');
nodes.push(element);
while(element.parentNode) {
nodes.unshift(element.parentNode);
element = element.parentNode;
}
Run Code Online (Sandbox Code Playgroud)
我喜欢这个方法:
[...(function*(e){do { yield e; } while (e = e.parentNode);})($0)]
Run Code Online (Sandbox Code Playgroud)
...其中 $0 是您的元素。
此方法的一个优点是它可以用作表达式中的值。
要获取没有目标元素的数组:
[...(function*(e){while (e = e.parentNode) { yield e; }})($0)]
Run Code Online (Sandbox Code Playgroud)
您可以遍历 s 链,element.parentNode直到达到 false 值,并在执行过程中附加到数组:
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));Run Code Online (Sandbox Code Playgroud)
<div><p><span><b>Foo</b></span></div>Run Code Online (Sandbox Code Playgroud)
请注意,反转是在调用方中完成的,因为它对于沿袭算法来说并不是必需的。映射到e.nodeName纯粹是为了演示,也不是必需的。
请注意,这种方法意味着您最终会将文档元素作为链中的最后一个元素。如果您不想这样做,可以添加&& el !== document循环停止条件。
上面代码的总体时间复杂度是线性的并且reverse()是就地的,因此不需要额外的分配。unshift正如其他一些答案所建议的那样,循环中的循环是二次的,并且可能会损害异常深的 DOM 树的可扩展性,以换取可忽略不计的优雅增益。