如何解决选择距索引 n 距离的同级 (JavaScript)
我正在寻找一种方法来遍历 DOM 元素兄弟元素,如 .nextSibling()
允许,但在任何给定距离,而不是仅直接下一个兄弟元素。
例如,如果我想相对于当前节点移动 3 个兄弟节点,我可以执行诸如 nextSibling(3)
或 siblings[2]
之类的操作。
关于如何在不循环 nextSibling n 次的情况下完成此操作的任何想法?
解决方法
您可以使用 parent.children
数组以及 Array.prototype.indexOf
函数。
function strideSiblings(element,stride){
var parent = element.parentNode;
var index = Array.prototype.indexOf.call(parent.children,element);
return parent.children[index + stride];
}
var el = document.getElementById("div-3");
var stridedSibling = strideSiblings(el,-2);
var stridedSibling1 = strideSiblings(el,1);
console.log(stridedSibling);
console.log(stridedSibling1);
<div id="parent">
<div id="div-1">Here is div-1</div>
<div id="div-2">Here is div-2</div>
<div id="div-3">Here is div-3</div>
<div id="div-4">Here is div-4</div>
<div id="div-5">Here is div-5</div>
</div>
这个答案建立在 KhalilRavanna 的贡献之上:https://stackoverflow.com/a/23528539/9298528
,我想在循环中使用 previousSibling
和 nextSibling
属性进行一些测试运行,而不是使用已接受的答案,我看到 没有 从 中受益不使用内置节点属性和 for
循环,我看到使用带有 for
循环的属性而不是接受的答案的性能优势,这是我的基准不同数量的兄弟姐妹以及用于运行更多基准测试的 jsfiddle - (https://jsfiddle.net/b196t7r3/),所以简而言之,我的答案是使用您在问题中反对的解决方案,以下数字是使用运行 jsfiddle 收到的 - Chrome 版本 88.0.4324.146(官方版本)(64 位):
100,000 个兄弟姐妹:
Accepted answer execution time - 21.915000048466027 milliseconds
Using properties with for loop - 8.234999957494438 milliseconds
10,000 个兄弟姐妹:
Accepted answer execution time - 0.8149999775923789 milliseconds
Using properties with for loop - 0.19500002963468432 milliseconds
1,000 个兄弟姐妹:
Accepted answer execution time - 0.1800000318326056 milliseconds
Using properties with for loop - 0.059999991208314896 milliseconds
编辑:在此处添加了一个代码片段,以便不需要外部网站:
const numberOfSiblings = 100000; //Number of divs to append to parent
const startingElement = "div-3000"; //id of element we want to pass into functions
const strideNum = 2000; //Number of siblings away from the chosen starting point
function strideSiblings(element,stride){
var parent = element.parentNode;
var index = Array.prototype.indexOf.call(parent.children,element);
return parent.children[index + stride];
}
function strideSiblingsWithPreviousOrNext(element,stride){
let sib = null;
if(stride > 0){
for(let i = 0; i < stride; i++){
sib = element.nextSibling;
element = sib;
}
}else{
stride = stride * -1;
for(let j = 0; j < stride; j++){
sib = element.previousSibling;
element = sib;
}
}
return sib;
}
let par = document.getElementById("parent"); //get the parent div
//append the number of siblings for benchmark testing
for(let v = 0; v < numberOfSiblings; v++){
let newDiv = document.createElement("div");
newDiv.id = "div-" + v;
newDiv.textContent = "Here is div-" + v;
par.append(newDiv);
}
var el = document.getElementById(startingElement); //get the sibling to start from
var t0 = performance.now()
var stridedSibling = strideSiblings(el,strideNum);
var t1 = performance.now()
console.log("Call to strideSiblings() took " + (t1 - t0) + " milliseconds.");
var t2 = performance.now();
stridedSibling = strideSiblingsWithPreviousOrNext(el,strideNum);
var t3 = performance.now();
console.log("Call to strideSiblingsWithPreviousOrNext() took " + (t3 - t2) + " milliseconds.");
<div id="parent">
</div>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。