2012-01-10 2 views
12

Ho bisogno di conoscere l'indice dell'elemento selezionato. Non riesco a capire come farloOttieni l'indice dell'elemento selezionato utilizzando puro javascript

for (i = 0; i < document.getElementById('my_div').children.length; i++) { 
    document.getElementById('my_div').children[i].onclick = function(){'ALERT POSITION OF CLICKED CHILD'}; 
} 

this.index?

ecco un esempio di quello che sto cercando di fare (si dà solo back 6):

<!DOCTYPE html> 
<html> 
<head> 
<meta charset="utf-8" /> 
<title>Untitled Document</title> 
<style type="text/css"> 
body{margin:0;} 
#container div{height:50px;line-height:50px; text-align:center} 
</style> 
</head> 
<body> 
<div id="container"> 
<div>1</div> 
<div>2</div> 
<div>3</div> 
<div>4</div> 
<div>5</div> 
<div>6</div> 
</div> 
<script> 
for (i = 0; i < document.getElementById('container').children.length; i++) { 
    document.getElementById('container').children[i].onclick = function(){alert('Number ' + i + ' was clicked')}; 
} 
</script> 
</body> 
</html> 
+0

possibile duplicato di [chiusura JavaScript all'interno di loop - esempio pratico semplice] (http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) –

risposta

28

Ecco un piece of code che può aiutare a ottenere l'indice dell'elemento cliccato all'interno del ciclo for. Tutto ciò che serve è un nuovo scope:

var g = document.getElementById('my_div'); 
for (var i = 0, len = g.children.length; i < len; i++) 
{ 

    (function(index){ 
     g.children[i].onclick = function(){ 
       alert(index) ; 
     }  
    })(i); 

} 

Edit 1: commenti di Incorporando dell'utente Felix Kling nella risposta.

gestore di eventi è già una chiusura

Edit 2: Aggiornato collegamento violino

+0

GRAZIE Brutallus! Questo è quello che volevo :) – Hakan

+0

Benvenuto :) Passare attraverso il link per saperne di più sulle chiusure. –

+3

In senso stretto il gestore dell'evento già ** è ** una chiusura. Ciò di cui l'OP aveva bisogno era un nuovo ambito. –

1

L'indice in relazione a che cosa?

Se si tratta dell'indice all'interno della raccolta HTML corrente, l'indice sarà rappresentato semplicemente con la variabile contatore i.

Una parola di cautela: poiché HTMLCollections sono "Live", dovresti sempre usarli per calcolare lo .length all'interno di un ciclo. Se accade che tali elementi vengano aggiunti o rimossi all'interno del loop, possono accadere cose strane e pericolose. Memorizza il valore .length prima di chiamare il ciclo.

+0

'i' non lavoro :(lui avrebbe bisogno di avvolgerlo – david

+0

@david: anzi, completamente dimenticato di questo fatto :) – jAndy

+0

Grazie jAndy. L'indice relativo agli altri bambini. Aggiunto un esempio se vuoi dare un'occhiata – Hakan

2

Gli elementi di tabella hanno una proprietà cellIndex, ma non conosco altri elementi. Vi sia necessario

  • creare una chiusura per riservare il valore di i
  • contano dinamicamente previousSibling s
  • aggiungere una proprietà index nella for-loop e letto che (non aumentare oggetti host) .

L'approccio di chiusura sarà il più semplice, penso. Assicurati di aver capito come funzionano le chiusure, ci sono buone spiegazioni sul web.

function makeAlertNumber(element, i) { 
    element.addEventListener('click', function() { 
     alert('Number ' + i + ' was clicked'); 
    }, false); 
} 
[].slice.call(document.getElementById('container').children).forEach(makeAlertNumber); // homework: find a way to express this for older browsers :-) 
+0

THanks Bergi, ti piacerebbe mostrare un esempio nel codice che ho aggiunto? – Hakan

+0

@Hakan: esempio aggiunto – Bergi

0

getIndexOfNode: function(node){ var i = 1; while(node.previousElementSibling != null){ i++ } return i; }
la funzione restituirà l'indice del nodo passato in suo elemento genitore.

+1

'node' non cambia mai, quindi questo è un ciclo infinito. – Johnny5k

7

Con ES6 destrutturazione si può fare

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

o

const index = Array.from(el.parentElement.children).indexOf(el) 

o versione ES5

var index = Array.prototype.slice.call(el.parentElement.children).indexOf(el) 
+0

Questo è incredibile !!! – fearis

-1

Se si sta creando il layout di pagina, e avere il controllo di come molti ' subdivs 'sarà racchiuso da' container ', perché non usare javascript per crearlo tutto in modo dinamico?

0

La risposta accettata (da Ashwin Krishnamurthy) è in realtà tutt'altro che ottimale.

si può solo fare:

const g = document.getElementById('my_div'); 
for (let i = 0, len = g.children.length; i < len; i++) 
{ 
    g.children[i].onclick = function(){ 
     alert(index) ; 
    } 
} 

per evitare di creare inutili chiusure. E anche in questo caso non è ottimale dato che stai creando 6 gestori di eventi DOM (6 divs nell'esempio sopra) solo per ottenere un numero di un singolo clic su div.

Che cosa si dovrebbe effettivamente fare è utilizzare una delegazione evento (allegare singolo evento click al genitore) e poi di controllo indice s' il e.target utilizzando il metodo che ho detto prima e al di sopra (Get index of clicked element using pure javascript).

+0

Non sono sicuro del motivo per cui questo ha -1 poiché è la soluzione migliore di qualsiasi altro menzionato qui;) – MelkorNemesis