对于通过Ajax响应添加到DOM的元素,jQuery自动注册用户操作的事件处理程序 [英] jQuery automatically register event handler(s) to user actions on elements that are added to DOM by Ajax response

查看:127
本文介绍了对于通过Ajax响应添加到DOM的元素,jQuery自动注册用户操作的事件处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于具有多个屏幕和导航功能的ajax Web应用程序,要附加div或链接或按钮的事件处理程序,我们可以编写如下代码:

  //在Ajax中使用$ .on成功处理程序

$(#container)。on(click,#selector,function(event){

});




  • 如果容器不存在,此方法将不起作用在DOM中。为了使其工作,将不得不使用文档或正文作为容器,性能可能不太好。


  • 在Ajax中可能有多行代码成功处理程序要组织更好,可以将代码移动到一个函数,并在Ajax成功处理程序中调用该函数。但是,我们必须对所有的排列和组合进行许多注册事件功能。


  • 注册功能代码混乱。


  • 如果事件处理程序已经注册,会造成两个甚至处理程序。所以我们必须取消注册和注册(如果没有附加,请附加) - 不确定性能问题。




任何替代方案?



我正在考虑以下几点:




  • 维护一个容器,目标和单击事件处理程序在一个地方的模块映射。

  • 在ajaxComplete全局事件处理程序中,如果xhr.responseHTML具有容器,请将事件处理程序附加到目标元素(仅在未附加时才附加)。

      $(document).ajaxComplete(function(e,xhr,settings){
    for(ind in clickEventListeners) {eventlistner = clickEventListeners [ind];
    if($(eventlistner.container,xhr.responseHTML).length> 0){
    $(eventlistner.target).on(click,function ){
    eventlistner.processor(this);
    });
    }
    }
    });




优点:一个地方记录的所有事件处理程序一个模块对于每个ajax成功处理程序,没有代码混乱。



缺点:我不知道是否有。



请建议任何建议。

解决方案

已更新



将事件绑定到要动态添加的元素需要将侦听器放在文档上,而不是1.9+以上的元素。从Jquerys api可以找到这一行:



事件处理程序仅限于当前选定的元素;它们必须存在于页面上,当您的代码进行调用到.on()。



因此将事件绑定到文档,然后放置选择器将允许此侦听器实际被识别。

  $(document).delegate(#selector,click,

  $(document).on(click选择器,

示例: http://jsfiddle.net/2HA7d/



在以前的Jquery版本中,可以使用live()函数实际上将收听者放置到文档中,允许这样完全按照您的想法运行:

  $(#selector) (click,

示例: http://jsfiddle.net/q3jYB/



第二个例子与第一个例子相同。



由于元素不存在,javascript无法为要查找的元素添加事件侦听器。所以,当试图为动态添加的元素添加一个监听器,并且你正在使用一个较新的jquery版本(1.9+)并使用on()或delegate()时,将事件侦听器添加到第一个提供的Fiddle中。 / p>

编辑:



正如我在评论中所说,添加事件收件人到容器,如果可能,也是一个非常可行的选择,可以提高性能。



资料来源:



https://api.jquery.com/on/



http://jquery.com/upgrade-guide/1.9/



jQuery .live()如何工作?



希望这有帮助。


For ajax web application that has many screens and navigations, to attach event handlers for div or links or buttons, we can code like :

//Using $.on inside Ajax success handler

$("#container").on("click", "#selector", function(event){

});

  • This approach will NOT work if container doesn't exists in the DOM. To make it work, will have to use document or body as the container, the performance may not be good.

  • There could be many lines of code in Ajax success handler. To organize better, can move the code to a function and call that function in Ajax success handler. But we have to make many register event functions for all permutations and combinations.

  • Register functions code cluttering.

  • If event handler was already registered, registering again will cause two even handlers. So we have to un-register and register (OR attach only if not attached already) - Not sure about performance problem.

Any alternatives ?

I am thinking of following :

  • Maintain a map of container, target, and click event handler in one place for a module.
  • In ajaxComplete global event handler, if xhr.responseHTML has the container, attach event handler to target elements (attach only if not attached already).

    $(document).ajaxComplete(function(e, xhr, settings){
       for(ind in clickEventListeners){eventlistner = clickEventListeners[ind];
        if($(eventlistner.container,xhr.responseHTML).length > 0){
          $(eventlistner.target).on("click",function(){
          eventlistner.processor(this);
          });
      }
     }
    });
    

Pros : All event handlers documented in one place for a module. No code cluttering in for each ajax success handler.

Cons : I am not sure if any.

Please advise if any suggestions.

解决方案

Updated

Binding an event to an element that will be dynamically added requires placing the listener on the document, not the element as of version 1.9+. From Jquerys api you can find this line:

"Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on()."

Therefor binding the event to the document and placing the selector afterwards will allow this listener to actually be recognized.

$(document).delegate( "#selector", "click",

or

$(document).on( "click", "#selector",

Example: http://jsfiddle.net/2HA7d/

In previous Jquery releases the live() function could have been used which actually placed the listener to the document allowing this to function exactly as you would think:

$("#selector").live("click",

Example: http://jsfiddle.net/q3jYB/

The second example functions the same as the first example.

As the element does not exist yet, javascript is unable to add an event listener for the element you are looking for. So, when trying to add a listener for dynamically added elements and you are using a newer jquery version (1.9+) and using on() or delegate(), add your event listener to the document as seen in the first Fiddle provided.

Edit:

as Will I AM stated in the comments, adding the event listener to the container if possible is also a very viable option and may improve performance

Sources:

https://api.jquery.com/on/

http://jquery.com/upgrade-guide/1.9/

How does jQuery .live() work?

Hope this helps.

这篇关于对于通过Ajax响应添加到DOM的元素,jQuery自动注册用户操作的事件处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆