2013-05-16 7 views
129

Sto cercando di imparare JS e ho riscontrato un problema.Il gestore di clic JavaScript non funziona come previsto all'interno di un ciclo for

Ho provato molte cose e su Google ma invano. La seguente parte di codice non funziona come previsto. Dovrei ottenere il valore di io al clic ma restituisce sempre 6. Sto tirando i miei capelli fuori, per favore aiuto.

for (var i = 1; i < 6; i++) { 

    console.log(i); 

    $("#div" + i).click(
     function() { 
      alert(i); 
     } 
    ); 
} 

jsfiddle

+3

Hai a che fare con una chiusura: http://stackoverflow.com/questions/111102/how -Non-javascript-chiusure-lavoro – ajm

risposta

76

Working DEMO

Questo è un classico problema di chiusura JavaScript. Il riferimento all'oggetto i viene archiviato nella chiusura del gestore di clic, anziché il valore effettivo di i.

Ogni singolo gestore di clic fa riferimento allo stesso oggetto perché c'è un solo oggetto contatore che contiene 6 in modo da ottenere sei su ciascun clic.

La soluzione è di avvolgere questo in una funzione anonima e passare i come argomento. I primitivi vengono copiati in base al valore delle chiamate di funzione.

for(var i=1; i<6; i++) { 
    (function (i) { 
     $("#div" + i).click(
      function() { alert(i); } 
     ); 
    })(i); 
} 

UPDATE

Updated DEMO

Oppure si può utilizzare al posto 'let'var di dichiarare i. let fornisce ogni volta una nuova rilegatura. Può essere utilizzato solo in ECMAScript 6 strict mode.

'use strict'; 

for(let i=1; i<6; i++) { 

     $("#div" + i).click(
      function() { alert(i); } 
     ); 
} 
6
$("#div" + i).click(
    function() { 
     alert(i); 
    } 
); 

E 'perché è utilizzando il valore di i come chiusura. i viene ricordato attraverso una chiusura che aumenta in ogni fase del ciclo foor.

$("#div" + i).click(function(event) { 
    alert($(event.target).attr("id").replace(/div/g, "")); 
}); 
14

Il problema è che, come eseguire iterazioni del ciclo, i viene incrementato. Si finisce con un valore di 6. Quando si dice alert(i) si sta chiedendo javascript per dirti quello che il valore di i è al momento il link viene cliccato, che a quel punto è 6.

Se si desidera per ottenere il contenuto della scatola, invece si potrebbe fare qualcosa di simile:

for (var i = 1; i < 6; i++) { 

    console.log(i); 

    $("#div" + i).click(function(e) { 
     alert($(this).text()); 
    }); 
} 

esempio di lavoro: http://jsfiddle.net/rmXcF/2/