2012-01-28 8 views
1

http://jsfiddle.net/tAfkU/ループ内のオブジェクトを適切に参照するにはどうすればよいですか?私は配列をループしていた場合

を参照してください、どのように私はループ内でコールバックをバインドされてきた配列の正しい要素を参照することができますか?

var items = ["a", "b", "c"]; 
for(var i in items) { 
    var this_item = items[i]; 
    var new_li = $('<li>'+this_item+'</li>'); 
    new_li.bind('click', function() { 
     alert(this_item); // this always alerts "c" 
    }); 
    $('.container').append(new_li); 
} 
+0

「for-in」配列を使用しないでください。それは本当に悪い習慣です。 –

+0

これは範囲の問題です。このブログの投稿はあなたを助けます。 http://www.mennovanslooten.nl/blog/post/62 – Alex

答えて

3

あなたはその変数の上にクロージャを作成したいと思う:

var createCallback; 

createCallback = function(item) { 
    return function() { 
    alert(item); 
    }; 
}; 
for(var i in items) { 
    var this_item = items[i]; 
    var new_li = $('<li>'+this_item+'</li>'); 
    new_li.bind('click', createCallback(this_item)); 
    $('.container').append(new_li); 
} 

は、バインドされた機能が後でそのループはそうthis_itemの値は、それが最後に設定されたものは何でもある終えると呼ばれていることを忘れないでください。 Javascriptはすべてのループ反復に対して新しいスコープを作成しないので、コールバックを定義する場合は、自分で作成する必要があります。 JSでスコープを作成する唯一の方法は、関数を使用することです。そこで、値を引数としてバインドし、適切な値を「記憶」する新しい関数を返す関数を書きました。

-1

jQueryで.data()メソッドを使用してみてください。

var items = ["a", "b", "c"]; 
for(var i in items) { 
    var this_item = items[i]; 
    var new_li = $('<li>'+this_item+'</li>'); 
    new_li.data("item", this_item).bind('click', function() { 
     alert($(this).data("item")); 
    }); 
    $('.container').append(new_li); 
} 
0

問題は、すべての要素の「クリック」を同じ変数にバインドすることです。また、配列の値を反復処理するたびにこの変数を定義するので、クリックは常に変数(c)に割り当てられた最後の値を返します。

Heres実際のオブジェクトを取得して.text()を返すだけでリスト項目内に設定するので、実際の値を取得するための解決策です。

var items = ["a", "b", "c"]; 
for(var i in items) { 
    var this_item = items[i], 
     new_li = $('<li>'+this_item+'</li>'); 
    new_li.bind('click', function() { 
     alert($(this).text()); 

     //alert(this_item); // this always alerts "c" 
    }); 
    $('.container').append(new_li); 
} 
関連する問題