JavaScript DOM:在容器中查找元素索引

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11761881/
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-24 07:00:57  来源:igfitidea点击:

JavaScript DOM: Find Element Index In Container

javascripthtmldomparent-child

提问by Vad

I need to find an index of element inside its container by object reference. Strangely, I cannot find an easy way. No jQuery please - only DOM.

我需要通过对象引用在其容器内找到元素的索引。奇怪的是,我找不到简单的方法。请不要使用 jQuery - 只有 DOM。

UL
 LI
 LI
 LI - my index is 2
 LI

Yes, I could assign IDs to each element and loop through all nodes to match the ID but it seems a bad solution. Isn't there something nicer?

是的,我可以为每个元素分配 ID,并遍历所有节点以匹配 ID,但这似乎是一个糟糕的解决方案。没有更好的东西吗?

So, say I have an object reference to the third LI as in the example above. How do I know it is index 2?

所以,假设我有一个对第三个 LI 的对象引用,如上例所示。我怎么知道它是索引 2?

Thanks.

谢谢。

回答by jAndy

You could make usage of Array.prototype.indexOf. For that, we need to somewhat "cast" the HTMLNodeCollectioninto a true Array. For instance:

你可以使用Array.prototype.indexOf. 为此,我们需要在某种程度上将 theHTMLNodeCollection转换为 true Array。例如:

var nodes = Array.prototype.slice.call( document.getElementById('list').children );

Then we could just call:

然后我们可以调用:

nodes.indexOf( liNodeReference );

Example:

例子:

var nodes = Array.prototype.slice.call( document.getElementById('list').children ),
    liRef = document.getElementsByClassName('match')[0];

console.log( nodes.indexOf( liRef ) );
<ul id="list">
    <li>foo</li>
    <li class="match">bar</li>
    <li>baz</li>    
</ul>

回答by Tim Down

2017 update

2017年更新

The original answer below assumes that the OP wants to include non-empty text node and other node types as well as elements. It doesn't seem clear to me now from the question whether this is a valid assumption.

下面的原始答案假设 OP 想要包含非空文本节点和其他节点类型以及元素。我现在似乎不清楚这是否是一个有效的假设。

Assuming instead you just want the element index, previousElementSiblingis now well-supported (which was not the case in 2012) and is the obvious choice now. The following (which is the same as some other answers here) will work in everything major except IE <= 8.

假设您只想要元素索引,previousElementSibling现在得到了很好的支持(2012 年不是这种情况)并且现在是显而易见的选择。以下(与此处的其他一些答案相同)适用于除 IE <= 8 之外的所有主要内容。

function getElementIndex(node) {
    var index = 0;
    while ( (node = node.previousElementSibling) ) {
        index++;
    }
    return index;
}

Original answer

原答案

Just use previousSiblinguntil you hit null. I'm assuming you want to ignore white space-only text nodes; if you want to filter other nodes then adjust accordingly.

使用previousSibling直到你击中null。我假设您想忽略纯空白文本节点;如果要过滤其他节点,则相应地进行调整。

function getNodeIndex(node) {
    var index = 0;
    while ( (node = node.previousSibling) ) {
        if (node.nodeType != 3 || !/^\s*$/.test(node.data)) {
            index++;
        }
    }
    return index;
}

回答by Julien BONNIN

Here is how I do (2018 version ?):

这是我的做法(2018 版?)

const index = [...el.parentElement.children].indexOf(el);

Tadaaaam. And, if ever you want to consider raw text nodes too, you can do this instead :

塔达阿姆。而且,如果您也想考虑原始文本节点,您可以这样做:

const index = [...el.parentElement.childNodes].indexOf(el);

I spread the children into an array as they are an HTMLCollection (thus they do not work with indexOf).

我将孩子们分散到一个数组中,因为它们是一个 HTMLCollection(因此它们不适用于 indexOf)。

Be careful that you are using Babel or that browser coverage is sufficient for what you need to achieve (thinkings about the spread operator which is basically an Array.from behind the scene).

请注意您正在使用 Babel 或者浏览器覆盖范围足以满足您需要实现的目标(关于扩展运算符的想法,它基本上是一个 Array.from 幕后)。

回答by Alexander Abashkin

Array.prototype.indexOf.call(this.parentElement.children, this);

Or use letstatement.

或者使用let语句。

回答by Web_Designer

For just elements this can be used to find the index of an element amongst it's sibling elements:

对于仅元素,这可用于在其兄弟元素中查找元素的索引:

function getElIndex(el) {
    for (var i = 0; el = el.previousElementSibling; i++);
    return i;
}

Note that previousElementSiblingisn't supported in IE<9.

请注意,previousElementSibling在 IE<9 中不支持。

回答by rsplak

You can use this to find the index of an element:

您可以使用它来查找元素的索引:

Array.prototype.indexOf.call(yourUl, yourLi)

Array.prototype.indexOf.call(yourUl, yourLi)

This for example logs all indices:

这例如记录所有索引:

var lis = yourList.getElementsByTagName('li');
for(var i = 0; i < lis.length; i++) {
    console.log(Array.prototype.indexOf.call(lis, lis[i]));
}?

JSFIDDLE

JSFIDDLE

回答by calipoop

A modern native approach could make use of 'Array.from()' - for example: `

现代本机方法可以使用 'Array.from()' - 例如:`

const el = document.getElementById('get-this-index')
const index = Array.from(document.querySelectorAll('li')).indexOf(el)
document.querySelector('h2').textContent = `index = ${index}`
<ul>
  <li>zero
  <li>one
  <li id='get-this-index'>two
  <li>three
</ul>
<h2></h2>

`

`

回答by berandomsen

An example of making an array from HTMLCollection

从 HTMLCollection 创建数组的示例

<ul id="myList">
    <li>0</li>
    <li>1</li>
    <li>2</li>
    <li>3</li>
    <li>4</li>
</ul>

<script>
var tagList = [];

var ulList = document.getElementById("myList");

var tags   = ulList.getElementsByTagName("li");

//Dump elements into Array
while( tagList.length != tags.length){
    tagList.push(tags[tagList.length])
};

tagList.forEach(function(item){
        item.addEventListener("click", function (event){ 
            console.log(tagList.indexOf( event.target || event.srcElement));
        });
}); 
</script>

回答by Rocket Hazmat

You can iterate through the <li>s in the <ul>and stop when you find the right one.

您可以遍历<li>s 中的s<ul>并在找到合适的时停止。

function getIndex(li) {
    var lis = li.parentNode.getElementsByTagName('li');
    for (var i = 0, len = lis.length; i < len; i++) {
        if (li === lis[i]) {
            return i;
        }
    }

}

Demo

演示

回答by Ada

If you want to write this compactly all you need is:

如果你想紧凑地写这个,你需要的是:

var i = 0;
for (;yourElement.parentNode[i]!==yourElement;i++){}
indexOfYourElement = i;

We just cycle through the elements in the parent node, stopping when we find your element.

You can also easily do:

我们只是循环遍历父节点中的元素,当我们找到你的元素时停止。

您还可以轻松执行以下操作:

for (;yourElement.parentNode.getElementsByTagName("li")[i]!==yourElement;i++){}

if that's all you want to look through.

如果这就是您想要查看的全部内容。