如何将对象传递给onclick事件

时间:2012-09-19 19:50:57

标签: javascript jquery

  

可能重复:
  Event handlers inside a Javascript loop - need a closure?

我通过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事件,第二个div应该有来自第二个对象的数据。 请问我是否需要进一步澄清

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

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

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

编辑: - 这就是我最终解决它的方式。感谢DCoder指向的链接。

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

         }(obj);

6 个答案:

答案 0 :(得分: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);
      }
    }
 }

答案 1 :(得分: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
    }
}

答案 2 :(得分:0)

当有人点击“item”时,会从jquery触发onclick事件。除非使用触发器函数触发,否则您不能指望自定义数据到事件处理程序。

答案 3 :(得分:0)

在js中执行异步调用时遇到了麻烦。这是一个常见问题,它在这里描述: http://dojo-toolkit.33424.n3.nabble.com/Advice-on-closures-and-retaining-variable-values-inside-async-handlers-e-g-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
});

答案 4 :(得分:0)

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

答案 5 :(得分: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对象数组。