【问题标题】:How to set up jQuery dynamic event handlers properly?如何正确设置 jQuery 动态事件处理程序?
【发布时间】:2016-02-08 05:06:22
【问题描述】:

我还是一个初学者,我尝试在动态 html 表中的<td> 中的类型(文本)输入上设置动态事件处理程序,代码如下:

for(var i=0; i<5; i++){
    table += '<td><input type="text" name="vote['+i+']"></td>';
    $("#table").on("keyup", "input[type='text'][name='vote["+i+"]']", function() {
        console.log("called: "+i);
        calculate(i);
    });
}

它没有工作。 i 的值(如console.log 中显示的那样)不是应有的值,即依次为0 到4,但始终为5。但在其他地方,我使用了类似下面示例中的模式,并且它有效。

$.each(array_parties, function(i, objParty) {
    var stationID = objStation.stationID;
    var partyID = objParty.partyID;
    table += '<td><input type="text" name="items['+stationID+']['+partyID+']"></td>';
    $("#table").on("keyup", "input[type='text'][name='items["+stationID+"]["+partyID+"]']", function() {
        calculateTotalByParty(json, partyID, khumID);
    });
});

请,有人可以帮助找出这里的问题吗?快把我逼疯了。

【问题讨论】:

  • 它正在形成一个闭包!
  • 是的,但正如我在第二个示例中所示,它应该可以正常工作。
  • 使用$.each不会出现问题
  • 哦,我不知道。现在可以了。非常感谢。

标签: jquery loops dynamic event-handling


【解决方案1】:

它形成了一个闭包。因此,只需将您的点击处理程序包含在一个自执行函数中,该函数会创建一个新范围。

问题是:由于 JavaScript 中的变量具有函数级作用域,因此您的循环每次都会覆盖“i”。因此,我们可以通过创建一个新作用域的匿名函数来避免这种情况。

for(var i=0; i<5; i++){
(function(j){
   table += '<td><input type="text" name="vote['+j+']"></td>';
   $("#table").on("keyup", "input[type='text'][name='vote["+j+"]']", function(){
         console.log("called: "+j);
         calculate(j);
    });
})(i)
}

举个例子:

问题:https://jsfiddle.net/sandenay/ar5f5m4t/

解决方案:https://jsfiddle.net/sandenay/m5p8740w/

【讨论】:

  • 是的,但是为什么$.each不覆盖变量的值呢?
  • 因为它为每次迭代创建匿名函数...正如您将在$.each(array, function(){.....})中看到的那样
【解决方案2】:

没有循环也可以正常工作

$("#table").on("keyup", "input[type='text'][name^='vote']", function() {
        console.log("called: "+i);
        calculate(i);
    });

【讨论】:

  • 是的,从运算符开始,但会涉及比想要的更多的元素。还是谢谢。
  • 在速度方面,你知道哪个更好吗?
  • 当然,这个。因为循环总是很昂贵。这会将 keyup 事件绑定到所有没有循环的输入。
  • 不,它只会绑定到名称以投票开头的输入元素,而不是所有元素
  • 是的,但我也有名称以 vote 开头的元素,但我从处理程序中排除。无论如何,谢谢,我会在设计数据结构时考虑到这一点。
【解决方案3】:

我有一个不同的棘手方法:

$(function(){

   //First, just build the table AND SAVE THE iterator in an tag atribute
   var table = "<tr>";
   for(var i=0; i<5; i++){
      table += '<td><input type="text" name="vote['+i+']" data-id="'+i+'">   </td>';
   }
   table += "</tr>";
   $("#table").html(table);

   // On event 'keyup', get the iterator saved in attrbute ( data-id ) and use it :)
   $("#table").on("keyup", "input[type='text']", function() {
     var i = $(this).attr("data-id");
     calculate(i);
   });

});

function calculate(i){
    console.log("Called to: "+i);
}

接下来,您可以将 building-html 函数(.html())与事件函数('keyup')分开。

Working jsfiddle

【讨论】:

  • 不错的方法!如果我们事先知道表的大小(行和列)。在我的例子中,行和列是动态链接到可用数据的。
猜你喜欢
  • 1970-01-01
  • 2012-03-29
  • 2015-03-23
  • 2019-01-03
  • 2010-09-22
  • 1970-01-01
  • 2014-04-24
  • 1970-01-01
  • 2012-09-28
相关资源
最近更新 更多