简体   繁体   English

动态添加元素上的多个事件绑定

[英]Multiple event binding on dynamically added elements

I have the following javascript jquery ajax call that is inside a for loop. 我在for循环内有以下javascript jquery ajax调用。

This loop does a call to an external api and appends an input button to an html element. 此循环调用外部api,并将输入按钮附加到html元素。 When this button is pressed it should show a popup alert box, but it popups multiple times as the for loop is attaching this click event to the button multiple times. 当按下此按钮时,它应该显示一个弹出警报框,但是当for循环将此点击事件附加到按钮多次时,它会弹出多次。

I also tried to put the .click() outside of the for loop, but that doesnt seem to work neither as the ajax is an async and the .click() event doesn't get attached to anything since its outside of the flow. 我还尝试将.click()放在for循环之外,但这似乎也不起作用,因为ajax是异步的,并且.click()事件由于未在流程之外而未附加到任何内容。

I tried to google this issue, but most people just have regular ajax async issues, but this time its in a loop and there doesnt seem to be much info on this setup. 我试图用谷歌搜索这个问题,但是大多数人都遇到了常规的ajax异步问题,但是这次是一个循环,关于此设置似乎没有太多信息。

  • How would one fix or improve this code? 一个人将如何修复或改进此代码? I'm sure its not the most efficient setup. 我确定它不是最有效的设置。
  • Do I have to use a callback function? 我必须使用回调函数吗?

Code

function successHandler(data, textStatus, jqXHR) {        
   jj = '<input class ="submitAsset"type="submit" value="'+ data
+'">';
   jQuery("#example").append(jj); 

  jQuery('.submitAsset').on("click", function() {                     
    alert("clicked");
  }); //function click
} //function successHandler                                           
for (i=0;i < 9; i++)  {
     $.ajax({   
       dataType: 'json',   
       url: 'http://example.com',   
       success: successHandler 
     });//ajax call-- get required information

}//for

The reason it is throwing multiple alerts is because same click handler is attached to element every time successhandler is called. 引发多个警报的原因是因为每次调用成功处理程序时,相同的单击处理程序都附加到元素。

You need to either use event delegation or attach the event in success event only to newly appended element: 您需要使用事件委托或将成功事件中的事件仅附加到新添加的元素:

1) Using event delegation: 1)使用事件委托:

function successHandler(data, textStatus, jqXHR) {
 jj = '<input class ="submitAsset"type="submit" value="'+ data +'">';
 jQuery("#example").append(jj);    
}
jQuery('#example').on("click",".submitAsset", function() {                     
  alert("clicked");
});

2) By adding click handler to last appended element: 2)通过向最后附加的元素添加点击处理程序:

function successHandler(data, textStatus, jqXHR) {        
 jj = '<input class ="submitAsset"type="submit" value="'+ data +'">';
 jQuery("#example").append(jj); 
 jQuery('.submitAsset:last').on("click", function() {                     
   alert("clicked");
  }); //function click
 } //function successHandler  

NOTE: I would recommend using event delegation in this case as it created less CPU overhead compared to multiple bindings. 注意:在这种情况下,我建议使用事件委托,因为与多个绑定相比,它创建的CPU开销更少。

You don't need to attach events in loop and attach events using event delegation 您不需要循环附加事件并使用事件委托附加事件

    function successHandler(data, textStatus, jqXHR) {        
         jj = '<input class ="submitAsset"type="submit" value="'+ data +'">';
         jQuery("#example").append(jj); 
    } //function successHandler                                           

   for (i=0;i < 9; i++) 
   {
         $.ajax({   
           dataType: 'json',   
           url: 'http://example.com',   
           success: successHandler 
         });//ajax call-- get required information

    }//for

   //and attache events using event delegation
   $("#example").on("click", "input.submitAsset", function() 
   {                     
        alert("clicked");
   }); 

The successHandler is being called multiple times and the event handler is registered multiple times with the class name. 将多次调用successHandler ,并使用类名多次注册事件处理程序。 So all the elements created already will get registered multiple times. 因此,所有已创建的元素将被多次注册。

To fix this, instead of registering the handler with jQuery('.submitAsset') , create the element jj by wrapping jQuery and register the onclick hander directly to the element as below, 要解决此问题,不要使用jQuery('.submitAsset')注册处理程序,而是通过包装jQuery创建元素jj ,并将onclick句柄直接注册到该元素,如下所示,

function successHandler(data, textStatus, jqXHR) {        
   jj = jQuery('<input class ="submitAsset"type="submit" value="'+ data
+'">');
   jQuery("#example").append(jj); 

   jj.on("click", function() {                     
    alert("clicked");
  }); //function click
} //function successHandler                                           
for (i=0;i < 9; i++)  {
     $.ajax({   
       dataType: 'json',   
       url: 'http://example.com',   
       success: successHandler 
     });//ajax call-- get required information

}

Otherwise, attach the event outside of the success handler as below, 否则,将event附加到成功处理程序之外,如下所示,

$("#example").on("click", ".submitAsset", function() 
   {                     
        alert("clicked");
   }); 

function successHandler(data, textStatus, jqXHR) {        
       jj = '<input class ="submitAsset"type="submit" value="'+ data
    +'">';
       jQuery("#example").append(jj); 


    } //function successHandler                                           
    for (i=0;i < 9; i++)  {
         $.ajax({   
           dataType: 'json',   
           url: 'http://example.com',   
           success: successHandler 
         });//ajax call-- get required information

    }

If tou have form then I don't think you need to add multiple Submit buttons instead you just add Button type otherwise you need to add return false or event.preventDefault() . 如果您有表单,那么我认为您不需要添加多个Submit buttons而只需添加Button类型,否则您需要添加return falseevent.preventDefault() So I suggest to use button type and use event delegation like, 所以我建议使用button类型并使用事件委托,例如

function successHandler(data, textStatus, jqXHR) {
   // you are using json as dataType so you may need to get a key from data object
   jj = '<input class ="submitAsset" type="button" value="'+ data
+'">';
   jQuery("#example").append(jj); 
}

jQuery("#example").on("click", '.submitAsset',function() {                     
    alert("clicked");
}); //function click

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

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