0

JQueryでいくつかのDIVを動的にアタッチしていますが、それぞれにクリックイベントをアタッチしたいのですが、これが私のやり方です

for (var i=0; i<CAItems.length; i++)
    {
        //alert(i);
        $('#UserWorldItems').append(
            $("<div id='ContextItm" + i + "' class='UserItem'><div class='UserItemBox'>" + 
                CAItems[i].Context + "</div><div class='UserItemBox AddPaddingToItem'>" + 
                CAItems[i].Action + "</div></div>").on("click" , function() { alert(i); } )
        );
    }

DIV は作成されますが、新しい div のいずれかをクリックすると起動される関数により、「11」というアラートが発生します (11 は i の最後の値です)。各 div が正しいインデックスでアラートを表示することをどのように解決できますか? (0,1,2,3....11)

4

5 に答える 5

0

スコープを作成するには、パラメーター i を使用して関数を作成し、クリックが完了したときに実行する関数を返す必要があります。ループからの i の値である param i を使用して無名関数を実行していることを確認してください。コピーのように、アラートには正しい値が含まれます。あなたの場合、 for は最後の値で終わります。クリックすると、 i の値を求めていたので常に同じでした。新しい変数があり、関数のスコープが異なります。

for (var i=0; i<CAItems.length; i++)
{
    //alert(i);
    $('#UserWorldItems').append(
        $("<div id='ContextItm" + i + "' class='UserItem'><div class='UserItemBox'>" + 
            CAItems[i].Context + "</div><div class='UserItemBox AddPaddingToItem'>" + 
            CAItems[i].Action + "</div></div>").on("click" , function (i) { return function() { alert(i); }; }(i) )
    );
}
于 2013-10-30T15:29:13.543 に答える
0

この問題に対処するより良い方法は、イベントを静的な親に委任することです。

$('#UserWorldItems').on('click', '.UserItem', function(e){
  e.preventDefault();

  // Your code
  // 'this' is set to the .UserItem element that was clicked
});

もちろん、 の値を取得することはできませんが、それが本当に必要な場合は、属性に (またはメソッドを介して)i追加することができます。data-*.data()

データを追加してインデックスを保存するには:

$("<div id='ContextItm" + i + "' class='UserItem'><div class='UserItemBox'>" + 
        item.Context + "</div><div class='UserItemBox AddPaddingToItem'>" + 
        item.Action + "</div></div>").data('index',i);

そして取得するには:

$(this).data('index');
于 2013-10-30T15:30:21.327 に答える
0

変数の周りにクロージャーが必要ですi:

.on("click" , function(i) { return function() { alert(i); } }(i) )
于 2013-10-30T15:31:31.410 に答える
0

次のようにすることをお勧めします。

// Make a function called createDiv,
// The arguments to the function is: item, index
var createDiv = function(item, i) {
    $('#UserWorldItems').append(
        $("<div id='ContextItm" + i + "' class='UserItem'><div class='UserItemBox'>" + 
            item.Context + "</div><div class='UserItemBox AddPaddingToItem'>" + 
            item.Action + "</div></div>"
        ).on("click" , function() {
            alert(i);
        })
    );
};
// Iterate your array and call createDiv:
for (var i=0; i<CAItems.length; i++) {
    createDiv(CAItems[i], i);
}
// Actually now you can use:
// CAItems.forEach(createDiv);
于 2013-10-30T15:31:35.977 に答える
0

コードの設計と効率を向上させる方法はいくつかあります。まず、jQuery の追加機能は、文字列に連結してから全体を一度に追加するよりも約80% 遅くなります。次に、読みやすくするためにコードをさらにクリーンアップするために、追加後にイベントをバインドできます。

var html = "";

for (var i = 0; i < CAItems.length; i++) {
    html += "<div id='ContextItm" + i + "' class='UserItem'><div class='UserItemBox'>"
        + CAItems[i].Context + "</div><div class='UserItemBox AddPaddingToItem'>"
        + CAItems[i].Action + "</div></div>";
}

$('#UserWorldItems').append(html);
$('#UserWorldItems .UserItem').click(function() {
    var id = this.id;
    var i = id.substring(id.length - 1);
    alert(i);
}

必要に応じて、各 div 要素にvalueoritem属性を追加し、jQuery の関数を介して簡単にアクセスできattr()ます。おそらく、各 div に完全に個別の ID は必要ないためですが、何を達成しようとしているのかわかりません。おそらくあなたはそうします。したがって、次のようになります。

var html = "";

for (var i = 0; i < CAItems.length; i++) {
    html += "<div id='ContextItm" + i + "' class='UserItem'><div class='UserItemBox'>"
        + CAItems[i].Context + "</div><div class='UserItemBox AddPaddingToItem'>"
        + CAItems[i].Action + " item='" + i + "'</div></div>";
}

$('#UserWorldItems').append(html);
$('#UserWorldItems .UserItem').click(function() {
    alert($(this).attr('item'));
}
于 2013-10-30T16:06:59.387 に答える