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

时间:2011-01-10 17:42:52

标签: javascript dom

通常我这样做:

for(i=0;i<elem.parentNode.length;i++) {
  if (elem.parentNode[i] == elem) //.... etc.. etc...
}

7 个答案:

答案 0 :(得分:34)

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仍然在函数调用中循环。没有循环就不可能做到这一点。

答案 1 :(得分:21)

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

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

答案 2 :(得分:13)

选项#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);
}

选项#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);
}

选项#3

您还可以使用spread operator

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

答案 3 :(得分:2)

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

  • 确保使用var
  • 声明变量“i”
  • 在比较中使用===代替==

答案 4 :(得分:2)

无法以某种方式循环获取其父节点内的节点索引,无论是for - 循环,Array方法如{ {1}}或indexOf或其他内容。 DOM中的操作索引是线性时间,而不是常量时间。

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

答案 5 :(得分:0)

If you have a collection input elements with the same name (like <textarea name="text_field[]"…) in your form and you want to get the exact numeric index of the field that triggered an event:

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;
}

Getting numeric id of an element from a collection of elements with the same class name:

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;
}

答案 6 :(得分:-1)

尝试一下:

let element = document.getElementById("your-element-id");
let indexInParent = Array.prototype.slice.call(element.parentNode.parentNode.children).indexOf(element.parentNode));