2012-09-19 50 views
3

可能重复:
Event handlers inside a Javascript loop - need a closure?如何将对象传递给onclick事件

我通过API call.It得到一些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事件应该从第二个对象中的数据的第一个div .. 请问我,如果任何更多的澄清需要

编辑: - 如果我做这样的事情: -

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

我得到的是,在所有项目的onclick事件特定对象,但是这不是我想要的

编辑: - 这是怎么了,我终于解决了它。感谢DCoder指出的链接。

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

     }(obj); 
+3

这是臭名昭着的Javascript关闭问题。 – SLaks

+0

在daffy之前可以多少次回答这个问题? – Shmiddty

+0

@Smiddty请再试一次... – noname

回答

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 
    } 
} 
+0

谢谢Shmiddty这真的是最接近我最终如何解决它.. – noname

+0

但你明白为什么你在第一个问题? – Shmiddty

+0

是的,我得到了..谢谢 – noname

0

当有人点击'item'时,jquery会触发onclick事件。除非使用触发函数触发,否则不能期望自定义数据通过事件处理程序。

+1

你误解了这个问题。 – SLaks

0

您在js中执行异步调用时遇到麻烦。这是一个普遍的问题,这是形容这里: http://dojo-toolkit.33424.n3.nabble.com/Advice-on-closures-and-retaining-variable-values-inside-async-handlers-e-g-xhrGet-td3227726.html

基本的i值是由您的console.log实际运行时间等于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 
}); 
2

你总是可以jQuery的data函数来存储和检索数据对象:

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); 
     } 
    } 
} 
0

在div(在循环中创建)中添加一个隐藏字段,保留任何你想要的东西。 然后点击div。在它内部找到隐藏的字段(div)并读取它的值。

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 

Fiddle

当然,你必须把它包在函数内部并通过data阵列你以前正在做的事情。

相关问题