2013-05-16 6 views
129

Próbuję nauczyć się JS i mam problem.Obsługa kliknięć JavaScript nie działa zgodnie z oczekiwaniami wewnątrz pętli for

Próbowałem wielu rzeczy i googled, ale wszystko na próżno. Poniższy fragment kodu nie działa zgodnie z oczekiwaniami. Powinienem dostać wartość i na kliknięcie, ale zawsze zwraca 6. Wyciągam włosy. Pomóż mi.

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

    console.log(i); 

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

jsfiddle

+3

masz do czynienia z zamknięciem: http://stackoverflow.com/questions/111102/how -do-javascript-closures-work – ajm

Odpowiedz

76

Working DEMO

Jest to klasyczny problem zamknięcie JavaScript. Odniesienie do obiektu i jest przechowywane w zamknięciu obsługi kliknięcia, a nie rzeczywistej wartości i.

Każdy uchwyt kliknięcia będzie odnosił się do tego samego obiektu, ponieważ istnieje tylko jeden obiekt licznika, który mieści 6, dzięki czemu uzyskujesz sześć przy każdym kliknięciu.

Sposób obejścia tego problemu polega na zawijaniu tego w anonimową funkcję i przekazywaniu i jako argumentowi. Prymitywy są kopiowane przez wartość w wywołaniach funkcji.

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

UPDATE

Updated DEMO

Albo można użyć 'let' zamiast var zadeklarować i. let zapewnia nowe wiązanie za każdym razem. Można go używać tylko w 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); 
    } 
); 

To dlatego, że jest za pomocą wartości i jako zamknięcie. i jest zapamiętany przez zamknięcie, które zwiększa się na każdym etapie pętli podłogowej.

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

Problem polega na tym, że w miarę wykonywania iteracji przez pętlę, wzrasta i. Kończy się o wartości 6. Kiedy mówisz alert(i) prosicie javascript, aby powiedzieć, co wartość i jest w czasie kliknięciu łącza, która w tym momencie jest 6.

Jeśli chcesz aby uzyskać zawartość pola zamiast mógłby zrobić coś takiego:

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

    console.log(i); 

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

przykład robocza: http://jsfiddle.net/rmXcF/2/

Powiązane problemy