Select 距离索引 n 处的同级 (JavaScript)
Select sibling at n distance from index (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 的贡献:
我想做一些在循环中使用 previousSibling
和 nextSibling
属性的测试运行,而不是使用已接受的答案,我看到 no受益于 not 使用内置节点属性和 for
循环,我看到使用带有 for
循环的属性比接受的答案,这是我的基准测试,其中包含不同数量的兄弟姐妹以及用于 运行 更多基准测试的 jsfiddle - (https://jsfiddle.net/b196t7r3/),所以简而言之,我的答案是使用您反对的解决方案您的问题,以下数字已收到 运行 jsfiddle 使用 - Chrome 版本 88.0.4324.146(官方构建)(64 位):
10万兄弟姐妹:
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>
我正在寻找一种方法来遍历 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 的贡献:
我想做一些在循环中使用 previousSibling
和 nextSibling
属性的测试运行,而不是使用已接受的答案,我看到 no受益于 not 使用内置节点属性和 for
循环,我看到使用带有 for
循环的属性比接受的答案,这是我的基准测试,其中包含不同数量的兄弟姐妹以及用于 运行 更多基准测试的 jsfiddle - (https://jsfiddle.net/b196t7r3/),所以简而言之,我的答案是使用您反对的解决方案您的问题,以下数字已收到 运行 jsfiddle 使用 - Chrome 版本 88.0.4324.146(官方构建)(64 位):
10万兄弟姐妹:
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>