Javascript 是否可以在不循环的情况下在其父节点中获取元素的数字索引?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4649699/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 13:27:13  来源:igfitidea点击:

Is it possible to get element's numerical index in its parent node without looping?

javascriptdom

提问by rsk82

Normally I'm doing it this way:

通常我是这样做的:

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

采纳答案by kennebec

You could count siblings... The childNodes list includes text andelement nodes-

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

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

回答by gsnedders

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

This seems to work in Opera 11, Firefox 4, Chromium 10. Other browsers untested. It will throw TypeError if node has no parent (add a check for node.parentNode !== undefinedif you care about that case).

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

Of course, Array.prototype.indexOfdoes still loop, just within the function call. It's impossible to do this without looping.

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

回答by Josh Crozier

Option #1

选项1

You can use the Array.from()methodto convert an HTMLCollectionof elements to an array. From there, you can use the native .indexOf()methodin order to get the index:

您可以使用该Array.from()方法将一个HTMLCollectionof 元素转换为一个数组。从那里,您可以使用本机.indexOf()方法来获取索引:

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

If you want the node index (as oppose to the element's index), then replace the childrenpropertywith the childNodesproperty:

如果您想要节点索引(与元素索引相反),则将children属性替换为childNodes属性

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

Option #2

选项#2

You can use the .call()methodto invoke the array type's native .indexOf()method. This is how the .index()methodis implemented in jQuery if you look at the source code.

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

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

Likewise, using the childNodesproperty in place of the childrenproperty:

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

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

Option #3

选项#3

You can also use the spread operator:

您还可以使用扩展运算符

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

回答by Jeff Walden

There is no way to get the index of a node within its parent without looping in somemanner, be that a for-loop, an Arraymethod like indexOfor forEach, or something else. An index-of operation in the DOM is linear-time, not constant-time.

如果不以某种方式循环,则无法在其父节点中获取节点的索引,无论是 - 循环,还是像or 之类forArray方法,或其他方式。DOM 中的索引操作是线性时间,而不是常量时间。indexOfforEach

More generally, if list mutations are possible (and the DOM certainly supports mutation), it's generally impossible to provide an index-of operation that runs in constant time. There are two common implementation tactics: linked lists (usually doubly) and arrays. Finding an index using a linked list requires a walk. Finding an index using an array requires a scan. Some engines will cache indexes to reduce time needed to compute node.childNodes[i], but this won't help you if you're searching for a node. Not asking the question is the best policy.

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

回答by Pointy

I think you've got it, but:

我想你已经明白了,但是:

  • make sure that variable "i" is declared with var
  • use ===instead of ==in the comparison
  • 确保变量“i”声明为 var
  • 在比较中使用===而不是==

回答by Eugeny K

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:

如果您的表单中有一个具有相同名称的集合输入元素(例如<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;
}

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

从具有相同类名的元素集合中获取元素的数字 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;
}

回答by Mattia Pontonio

Try this:

尝试这个:

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