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
Is it possible to get element's numerical index in its parent node without looping?
提问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 之类for的Array方法,或其他方式。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));

