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 !== undefined
if you care about that case).
这似乎适用于 Opera 11、Firefox 4、Chromium 10。其他浏览器未经测试。如果节点没有父节点,它将抛出 TypeError (node.parentNode !== undefined
如果您关心这种情况,请添加检查)。
Of course, Array.prototype.indexOf
does 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 HTMLCollection
of elements to an array. From there, you can use the native .indexOf()
methodin order to get the index:
您可以使用该Array.from()
方法将一个HTMLCollection
of 元素转换为一个数组。从那里,您可以使用本机.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 children
propertywith the childNodes
property:
如果您想要节点索引(与元素索引相反),则将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 childNodes
property in place of the children
property:
同样,使用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 Array
method like indexOf
or forEach
, or something else. An index-of operation in the DOM is linear-time, not constant-time.
如果不以某种方式循环,则无法在其父节点中获取节点的索引,无论是 - 循环,还是像or 之类for
的Array
方法,或其他方式。DOM 中的索引操作是线性时间,而不是常量时间。indexOf
forEach
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));