是否有可能在其父节点中获取元素的数字索引而不进行循环?

问题描述 投票:27回答:7

通常我这样做:

for(i=0;i<elem.parentNode.length;i++) {
  if (elem.parentNode[i] == elem) //.... etc.. etc...
}
javascript dom
7个回答
22
投票

你可以算兄弟姐妹...... childNodes列表包括文本和元素节点 -

function whichChild(elem){
    var  i= 0;
    while((elem=elem.previousSibling)!=null) ++i;
    return i;
}

38
投票
function getChildNumber(node) {
  return Array.prototype.indexOf.call(node.parentNode.childNodes, node);
}

这似乎适用于Opera 11,Firefox 4,Chromium 10.其他浏览器未经测试。如果节点没有父节点,它将抛出TypeError(如果你关心那个情况,请添加node.parentNode !== undefined的检查)。

当然,Array.prototype.indexOf仍然在函数调用中循环。没有循环就不可能做到这一点。


14
投票

Option #1

您可以使用Array.from() methodHTMLCollection元素转换为数组。从那里,您可以使用本机.indexOf() method来获取索引:

function getElementIndex (element) {
  return Array.from(element.parentNode.children).indexOf(element);
}

如果你想要节点索引(与元素的索引相反),那么用children property替换childNodes property

function getNodeIndex (element) {
  return Array.from(element.parentNode.childNodes).indexOf(element);
}

Option #2

您可以使用.call() method来调用数组类型的本机.indexOf()方法。如果你看一下源代码,就是如何在jQuery中实现.index() method

function getElementIndex(element) {
  return [].indexOf.call(element.parentNode.children, element);
}

同样,使用childNodes属性代替children属性:

function getNodeIndex (element) {
  return [].indexOf.call(element.parentNode.childNodes, element);
}

Option #3

你也可以使用spread operator

function getElementIndex (element) {
  return [...element.parentNode.children].indexOf(element);
}
function getNodeIndex (element) {
  return [...element.parentNode.childNodes].indexOf(element);
}

2
投票

我想你已经得到了它,但是:

  • 确保使用var声明变量“i”
  • 在比较中使用===而不是==

2
投票

没有办法在没有以某种方式循环的情况下获得其父节点内的节点的索引,无论是for循环,Array方法,如indexOfforEach,还是别的东西。 DOM中的操作索引是线性时间,而不是恒定时间。

更一般地说,如果列表突变是可能的(并且DOM肯定支持突变),通常不可能提供在恒定时间内运行的操作索引。有两种常见的实现策略:链表(通常是双重的)和数组。使用链表查找索引需要散步。使用数组查找索引需要扫描。一些引擎会缓存索引以减少计算node.childNodes[i]所需的时间,但如果您正在搜索节点,这对您没有帮助。不问问题是最好的政策。


0
投票

如果您的表单中有一个具有相同名称的集合输入元素(如<textarea name="text_field[]" ...),并且您希望获得触发事件的字段的确切数字索引:

function getElementIdxFromName(elem, parent) {
    var elms = parent[elem.name];
    var  i = 0;
    if (elms.length === undefined) // there is only one element with this name in the document
        return 0;
    while((elem!=elms[i])) i++;
    return i;
}

从具有相同类名的元素集合中获取元素的数字id:

function getElementIdxFromClass(elem, cl) {
    var elems = document.getElementsByClassName(cl);
    var  i = 0;
    if (elems.length > 0) {
        while((elem!=elems[i])) i++;
        return i;
    }
    return 0;
}

-1
投票

试试这个:

let element = document.getElementById("your-element-id");
let indexInParent = Array.prototype.slice.call(element.parentNode.parentNode.children).indexOf(element.parentNode));
© www.soinside.com 2019 - 2024. All rights reserved.