Ich muss einen Index des Elements in seinem Container durch Objektreferenz finden. Seltsamerweise kann ich keinen einfachen Weg finden. Bitte keine jQuery - nur DOM.
UL
LI
LI
LI - my index is 2
LI
Ja, ich könnte jedem Element IDs zuweisen und alle Knoten durchlaufen, um mit der ID übereinzustimmen, aber es scheint eine schlechte Lösung zu sein. Gibt es nicht etwas Schöneres?
Angenommen, ich habe einen Objektverweis auf den dritten LI wie im obigen Beispiel. Woher weiß ich, dass es Index 2 ist?
Vielen Dank.
Antworten:
Sie könnten Gebrauch machen von
Array.prototype.indexOf
. Dafür müssen wir das etwasHTMLNodeCollection
in ein wahres "verwandeln"Array
. Zum Beispiel:var nodes = Array.prototype.slice.call( document.getElementById('list').children );
Dann könnten wir einfach anrufen:
Beispiel:
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>
quelle
.childNodes
und.children
sind verschiedene Dinge..children
ist eine Teilmenge, nur eine Liste allerElementNodes
.previousElementSibling
Lösung ist besser, da sie Textknoten ausschließt und den Index des erwarteten Elements zurückgibt.const index = [...el.parentNode.children].indexOf(el)
Array.from( el.parentNode.children ).indexOf( el );
in diesem Fall eigentlich sehr bevorzugen , nur um die Lesbarkeit zu gewährleisten.Update 2017
Die ursprüngliche Antwort unten geht davon aus, dass das OP nicht leere Textknoten und andere Knotentypen sowie Elemente enthalten möchte. Aus der Frage, ob dies eine gültige Annahme ist, scheint mir jetzt nicht klar zu sein.
Angenommen, Sie möchten stattdessen nur den Elementindex,
previousElementSibling
wird jetzt gut unterstützt (was 2012 nicht der Fall war) und ist jetzt die offensichtliche Wahl. Das Folgende (was mit einigen anderen Antworten hier identisch ist) funktioniert in allen wichtigen Bereichen außer IE <= 8.function getElementIndex(node) { var index = 0; while ( (node = node.previousElementSibling) ) { index++; } return index; }
Ursprüngliche Antwort
Verwenden
previousSibling
Sie einfach, bis Sie treffennull
. Ich gehe davon aus, dass Sie nur Leerzeichen-Textknoten ignorieren möchten. Wenn Sie andere Knoten filtern möchten, passen Sie sie entsprechend an.function getNodeIndex(node) { var index = 0; while ( (node = node.previousSibling) ) { if (node.nodeType != 3 || !/^\s*$/.test(node.data)) { index++; } } return index; }
quelle
So mache ich das (Version 2018?) :
const index = [...el.parentElement.children].indexOf(el);
Tadaaaam. Und wenn Sie jemals auch Rohtextknoten berücksichtigen möchten, können Sie dies stattdessen tun:
const index = [...el.parentElement.childNodes].indexOf(el);
Ich verteile die Kinder in einem Array, da sie eine HTMLCollection sind (daher funktionieren sie nicht mit indexOf).
Achten Sie darauf, dass Sie Babel verwenden oder dass die Browserabdeckung für das, was Sie erreichen möchten, ausreicht (Überlegungen zum Spread-Operator, der im Grunde genommen ein Array.from hinter den Kulissen ist).
quelle
Array.from
zu den childNodes hinzugefügtconst index = [...Array.from(el.parentElement.children)].indexOf(el);
Array.prototype.indexOf.call(this.parentElement.children, this);
Oder verwenden Sie die
let
Anweisung.quelle
Für nur Elemente kann dies verwendet werden, um den Index eines Elements unter seinen Geschwisterelementen zu finden:
function getElIndex(el) { for (var i = 0; el = el.previousElementSibling; i++); return i; }
Beachten Sie, dass
previousElementSibling
dies in IE <9 nicht unterstützt wird.quelle
Sie können dies verwenden, um den Index eines Elements zu finden:
Array.prototype.indexOf.call(yourUl, yourLi)
Dies protokolliert zum Beispiel alle Indizes:
var lis = yourList.getElementsByTagName('li'); for(var i = 0; i < lis.length; i++) { console.log(Array.prototype.indexOf.call(lis, lis[i])); }
JSFIDDLE
quelle
previousElementSibling
Lösung ist besser, da sie Textknoten ausschließt und den Index des erwarteten Elements zurückgibt.Ein moderner nativer Ansatz könnte 'Array.from ()' verwenden - zum Beispiel: `
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>
`
quelle
Ein Beispiel für die Erstellung eines Arrays aus 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>
quelle
Wenn Sie dies kompakt schreiben möchten, brauchen Sie nur:
var i = 0; for (;yourElement.parentNode[i]!==yourElement;i++){} indexOfYourElement = i;
Wir durchlaufen einfach die Elemente im übergeordneten Knoten und halten an, wenn wir Ihr Element finden.
Sie können auch leicht tun:
for (;yourElement.parentNode.getElementsByTagName("li")[i]!==yourElement;i++){}
wenn das alles ist, was du durchschauen willst.
quelle
Sie können das
<li>
s im durchlaufen<ul>
und anhalten, wenn Sie das richtige gefunden haben.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
quelle
const nodes = Array.prototype.slice.call( el.parentNode.childNodes ); const index = nodes.indexOf(el); console.log('index = ', index);
quelle
Ein weiteres Beispiel, bei dem nur eine grundlegende Schleifen- und Indexprüfung verwendet wird
HTML
<ul id="foo"> <li>0</li> <li>1</li> <li>2</li> <li>3</li> <li>4</li> </ul>
JavaScript wird onload / ready ausgeführt oder nachdem ul gerendert wurde
var list = document.getElementById("foo"), items = list.getElementsByTagName("li"); list.onclick = function(e) { var evt = e || window.event, src = evt.target || evt.srcElement; var myIndex = findIndex(src); alert(myIndex); }; function findIndex( elem ) { var i, len = items.length; for(i=0; i<len; i++) { if (items[i]===elem) { return i; } } return -1; }
Laufendes Beispiel
jsFiddle
quelle
Übergeben Sie einfach die Objektreferenz an die folgende Funktion und Sie erhalten den Index
function thisindex(elm) { var the_li = elm; var the_ul = elm.parentNode; var li_list = the_ul.childNodes; var count = 0; // Tracks the index of LI nodes // Step through all the child nodes of the UL for( var i = 0; i < li_list.length; i++ ) { var node = li_list.item(i); if( node ) { // Check to see if the node is a LI if( node.nodeName == "LI" ) { // Increment the count of LI nodes count++; // Check to see if this node is the one passed in if( the_li == node ) { // If so, alert the current count alert(count-1); } } } } }
quelle