4

重複の可能性:
Javascript ループ内のイベント ハンドラー - クロージャーが必要ですか?

API 呼び出しを使用して json オブジェクトを取得しています。次の形式です。

{data:[{id:"1",name:"some1",url:"someurl1"},{id:"2",name:"some2",url:"someurl2"}...]}

私はjsonpの結果からそれを取得し、以下のように解析されます:-

function(results){
   for(var i=0;i<10;i++){
    item=document.createElement("div");
    item.innerHTML=results.data[i].name;
    item.onclick=function(){
        console.log(results.data[i]);  //--->this is where i am stuck 
      }
    }
 }

特定のオブジェクトをループから onclick イベントに渡すにはどうすればよいですか。つまり、作成された最初の div には最初のオブジェクトのデータを含む onclick イベントが必要であり、2 番目の div には 2 番目のオブジェクトのデータが必要です。

編集:- 私がこのようなことをした場合:-

item.onclick=function(){
  console.log(results.data[1])
}

すべてのアイテムの onclick イベントでその特定のオブジェクトを取得しますが、それは私が望むものではありません

編集:-これが私が最終的に解決した方法です。DCoderが指すリンクに感謝します。

item.onclick =function(object){
           return function(){
           //do something with the object
           }

         }(obj);
4

6 に答える 6

2

迅速な解決策:

function(results){
    for(var i=0;i<10;i++){
        (function(index){ // create a closure, this makes a new scope
            item=document.createElement("div");
            item.innerHTML=results.data[index].name;
            item.onclick=function(){
                console.log(results.data[index]);  //--->this is where i am stuck 
            }
        })(i);  // pass in i
    }
}
于 2012-09-19T20:13:51.630 に答える
2

データオブジェクトを保存および取得するために、常にjQueryのデータ関数を使用できます。

function(results){
  for(var i=0;i<10;i++){
    item=document.createElement("div");
    item.innerHTML=results.data[i].name;

    // Store object in data 
    $(item).data("results", results.data[i]);

    item.onclick=function(){
        // Retrieve the data needed
        var data = $(this).data("results");
        console.log(data);
      }
    }
 }
于 2012-09-19T20:10:07.593 に答える
0

div内に非表示フィールド(ループで作成)を追加し、必要なものを保持します。次に、divをクリックします。it(div)内の隠しフィールドを見つけて、その値を読み取ります。

于 2012-09-19T20:14:13.940 に答える
0

onclick イベントは、誰かが「アイテム」をクリックしたときに jquery から発生します。トリガー関数を使用してトリガーされない限り、イベント ハンドラーにカスタム データを期待することはできません。

于 2012-09-19T19:59:05.853 に答える
0

個人的には$.map、関数コールバックが反復ごとに新しい実行コンテキストを作成するように使用します。

質問にjQueryのタグを付けたので、コードは次のように簡単になります

$($.map(data, function(v, i) {
    return $('<div>').html(data[i].name).click(function() {
        console.log(data[i]);
    });
})).appendTo('body'); //appending for demonstration purposes

フィドル

もちろん、これを関数内にラップして、data以前と同じようにオブジェクトの配列を渡す必要があります。

于 2012-09-19T20:20:07.233 に答える
0

js 内で非同期呼び出しを行う際に問題が発生しています。これは一般的な問題であり、ここで説明されています: http://dojo-toolkit.33424.n3.nabble.com/Advice-on-closures-and-retaining-variable-values-inside-async-handlers-eg-xhrGet- td3227726.html

基本的に、の値は、console.log が実際に実行されるiまでに等しくなります。9

一般に、この問題を解決するには多くの方法がありますが、具体的な解決策はおそらく物事を大幅に再構築することです。この代替案 (jQuery が必要) を検討してください。

$.each(results, function(data) {
  var $el = $("<div></div>").html(data.name).click(function() { console.log(data) });
})

しかし、 jQuery.data()を使用して物を保存してから、このようなクリック イベントを使用.on()またはリッスンする方が良いでしょう。.delegate()

$.each(results, function(data) {
  var $el = $("<div></div>").addClass("yourThing").html(data.name).data("data", data);
})

// replace window with a closer parent if one exists
$(window).on("click", ".yourThing", function() {
   console.log($(this).data("data")); // retrieve data from jquerys .data() store
});
于 2012-09-19T20:06:46.830 に答える