简体   繁体   English

如何正确设置jQuery动态事件处理程序?

[英]How to set up jQuery dynamic event handlers properly?

I am still a beginner, and I tried to set up dynamic event handlers on input of type(text) in <td> in a dynamic html table, with the following code: 我还是一个初学者,我尝试使用以下代码在动态html表的<td>中的type(text)输入上设置动态事件处理程序:

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

It did not work. 这没用。 The value of i(as displayed in console.log) is NOT what it is supposed to be, that is, 0 to 4 successively, but always 5. But elsewhere I use similar patterns like in the example below, and it works. 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);
    });
});

Please, can somebody help identify the problem here? 请,有人可以帮助您在这里找到问题吗? It's driving me crazy. 这让我疯狂。

Its forming a closure. 其形成闭合。 So, just enclose your click handler inside a self executing function which creates a new scope. 因此,只需将点击处理程序封装在一个自执行函数中即可,该函数会创建一个新的作用域。

The problem is: since a variable in JavaScript has function level scope, your loop will overwrite the 'i' each time. 问题是:由于JavaScript中的变量具有函数级作用域,因此您的循环每次都会覆盖'i'。 Hence we can avoid this by having an anonymous function which creates a new scope. 因此,我们可以通过创建一个新作用域的匿名函数来避免这种情况。

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

As an example: 举个例子:

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

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

This will work fine without loop also 这也可以无循环运行

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

I have a different tricky approach: 我有另一种棘手的方法:

$(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);
}

Following this, you can separate the building-html function( .html() ) from the event function ( 'keyup' ). 之后,您可以将building-html函数( .html() )与事件函数( 'keyup' )分开。

Working jsfiddle 工作jsfiddle

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM