0

次のようにループ内に多数のオブジェクトを作成すると、次のようになります。

for(var i = 0; i < 5; i++)
{
    var data = { val: i * 2 };
    var obj = $('<li>Item</li>');

    $("ul").append(obj);

    obj.click(function()
    {
        alert(data.val);
        // Output is 8 for all items.

    });
}

ハンドラー内で最後に作成されたdataオブジェクトにのみアクセスできます。.click()

dataハンドラー内の関連オブジェクト(クリックされているjQueryオブジェクトと同時に作成されたオブジェクト)を参照するにはどうすればよいですか?

.attr()これまでは、個別のオブジェクトではなく、データを保持するためにjQueryオブジェクトにランダムな属性を割り当てることでこれを回避できましたが、そのアプローチから離れたいと思います。

私もこれを試しましたが、運がありませんでした:

var data = { val: i * 2 };
var obj = $('<li>Item</li>');

obj.data = data;

obj.click(function()
{
    // 'data' is undefined here i.e. not associated with $(this).
    alert($(this).data.val);

});
4

2 に答える 2

2

最初の例の問題は、変数のスコープによってわかりにくくなっています。JSでは、すべての変数に関数スコープがあるため、コードを書き直して、より明示的に次の結果になることを示します。

var i,data,obj;
for(i = 0; i < 5; i++) {
    data = { val: i * 2 };
    obj = $('<li>Item</li>');

    $("ul").append(obj);
    obj.click(function() {
        alert(data.val);
    });
}

dataこれで、ループ内に1つの変数があり、反復ごとに新しい変数ではないことがより明白になりました(Java、C#などの場合のように)。クリックハンドラーがこの変数を使用するときに渡される無名関数は、この変数を閉じます。その結果、関数がクリックハンドラーとして割り当てられたときに変数が持っていた値ではなく、関数が実行されたときの変数の現在の値が使用されます。

これを回避するには、データを要素自体に添付することができます。

ただし、コードobj.data = ...では、要素ではなく選択に値を付加します。次に同じ要素を選択すると、data.propertyのない新しいオブジェクトが作成されます。.data()代わりに、jQueryメソッドを使用できます。

obj.data('key',data);
obj.click(function() {
    alert($(this).data('key').val);
});

または、関数に値を埋め込みたい場合は、自己実行関数を使用してそれを行うことができます。変数を引数として関数に渡す場合、変数を閉じる代わりに現在の値を使用しています。

var i,
    data,
    obj,
    createClick = function(data) {
        return function(){
           alert(data.val);
        };
    };
for(i = 0; i < 5; i++) {
    data = { val: i * 2 };
    obj = $('<li>Item</li>');

    $("ul").append(obj);
    obj.click(createClick(data));
}

余談ですが{、行の先頭ではなく末尾に配置する習慣を身に付ける必要があります。次の行にある場合、セミコロンの挿入は予期しない結果をもたらす可能性があり{ます。例えば

return 
    {
      val : 1
    }

オブジェクトリテラルを無視したundefined後にセミコロンが挿入される可能性があるため、返される可能性がありますreturn

于 2012-11-07T05:25:07.790 に答える
2

jQuery .data()メソッドを使用できます。http://api.jquery.com/data/

例えば:

for(var i = 0; i < 5; i++){
    var obj = $('<li>Item</li>');
    obj.data('myData', {first: i * 2, second: i * 3});

    $("ul").append(obj);

    obj.click(function(){
        alert($(this).data('myData').first);
        alert($(this).data('myData').second);
    });
}
于 2012-11-07T05:25:37.863 に答える