2012-01-10 25 views
12

Necesito saber el índice del elemento cliqueado. No se puede averiguar cómo hacerloObtener índice del elemento cliqueado usando javascript puro

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?

aquí es un ejemplo de lo que estoy tratando de hacer (que sólo da vuelta 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

posible duplicado de [JavaScript closure inside loops - ejemplo práctico simple] (http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) –

Respuesta

28

Aquí es una piece of code que pueden ayudarle a obtener el índice del elemento se ha hecho clic dentro del bucle for. Todo lo que necesita es un nuevo 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); 

} 

Edición 1: los comentarios de incorporación de usuario Felix Kling en la respuesta.

controlador de eventos es ya un cierre

Edición 2: Actualizado enlace violín

+0

GRACIAS Brutallus! Eso es lo que quería :) – Hakan

+0

Sea bienvenido :) Vaya a través del enlace para saber más sobre los cierres. –

+3

Estrictamente hablando, el controlador de eventos ya ** es ** un cierre. Lo que el OP necesitaba era un nuevo alcance. –

1

El índice en relación a qué?

Si se trata del índice dentro de la colección HTML actual, el índice solo se representará con su variable de contador i.

Una palabra de advertencia: Dado que HTMLCollections están en "En vivo", debe utilizarlas para averiguar el .length dentro de un bucle. Si resulta que esos elementos se agregan o eliminan dentro del ciclo, pueden ocurrir cosas extrañas y peligrosas. Guarde en caché el valor .length antes de llamar al bucle.

+0

'i' no trabajo :(tendría que envolverlo. – david

+0

@david: en efecto. Totalmente se olvidó de este hecho :) – jAndy

+0

Gracias jAndy. El índice relacionado con los otros niños. Se agregó un ejemplo si desea tener un aspecto – Hakan

2

Los elementos de celda de tabla tienen una propiedad cellIndex, pero no sé sobre otros elementos. Hay que colocar a

  • crear un cierre a reservar el valor de i
  • contar dinámicamente previousSibling s
  • añadir una propiedad index en su ciclo for y leído que (no aumentar los objetos host) .

El enfoque de cierre será el más fácil, creo. Asegúrate de haber entendido cómo funcionan los cierres, hay buenas explicaciones en la 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, ¿desea mostrar un ejemplo en el código que agregué? – Hakan

+0

@Hakan: ejemplo agregado – Bergi

0

getIndexOfNode: function(node){ var i = 1; while(node.previousElementSibling != null){ i++ } return i; }
la función devolverá el índice del nodo pasado en su elemento padre.

+1

'node' nunca cambia, por lo que este es un ciclo infinito. – Johnny5k

7

Con ES6 desestructuración que puede hacer

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

o

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

o la versión ES5

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

Esto es increíble! – fearis

-1

Si va a crear su diseño de página, y tener un control de la cantidad de ' subdivs 'estará envuelto por' contenedor ', ¿por qué no utilizar javascript para crearlo todo de forma dinámica?

for (var i = 0; i < NumberOfSubDivsYouNeed; i++) { 
var SubDiv = document.createElement("DIV"); 
    SubDiv.id = i; 
    SubDiv.style.*enter any style rules if you wish*; 
    SubDiv.onclick=function(){alert(this.id);}; 
    document.getElementById("container").appendChild(SubDiv); 
    } 
0

La respuesta aceptada (de Ashwin Krishnamurthy) está lejos de ser óptima.

sólo se puede hacer:

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

para evitar la creación de cierres innecesarios. Y aun así no es óptimo ya que está creando 6 controladores de eventos DOM (6 divs en el ejemplo anterior) solo para obtener un número de div con un solo clic.

Lo que en realidad se debe hacer es utilizar una delegación de eventos (adjuntar solo evento clic al padre) y después de verificar los índices del e.target 's utilizando el método que he mencionado antes y por encima (Get index of clicked element using pure javascript).

+0

No estoy seguro de por qué esto tiene -1 ya que es la mejor solución que cualquiera de las mencionadas aquí;) – MelkorNemesis

Cuestiones relacionadas