6

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

//Using $.on inside Ajax success handler

$("#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 成功处理程序都没有代码混乱。

缺点:我不确定是否有。

如果有任何建议,请告知。

4

3 回答 3

9

更新

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

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

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

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

或者

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

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

在以前的 Jquery 版本中,可以使用 live() 函数,它实际上将侦听器放置到文档中,从而可以完全按照您的想法运行:

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

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

第二个示例的功能与第一个示例相同。

由于该元素尚不存在,javascript 无法为您要查找的元素添加事件侦听器。因此,当尝试为动态添加的元素添加侦听器并且您使用较新的 jquery 版本(1.9+)并使用 on() 或 delegate() 时,请将事件侦听器添加到文档中,如提供的第一个 Fiddle 所示。

编辑:

正如我在评论中所说的那样,如果可能的话,将事件侦听器添加到容器中也是一个非常可行的选择,并且可能会提高性能

资料来源:

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

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

jQuery .live() 是如何工作的?

希望这可以帮助。

于 2014-02-16T11:55:39.253 回答
1

我和你的情况类似,试试这个,这对我来说效果很好!

  • 首先在主文件中,我像这样绑定事件处理程序:

    $('body').bind( 'gridloaded', function(e,f) { my logic } );

  • 在最后动态填充我的 DOM 树的 ajax 文件中,我在需要的地方添加触发器和我所在的元素 id,如下所示:

    $('body').trigger('gridloaded', $(this).attr('id') );

    onClickButton: function(){ $("body").trigger("gridloaded", $(this).attr('id')) }

我喜欢这种方法,因为它很干净:无论 ajax 调用需要多长时间,它总是会在正确的时间只触发一个事件。

于 2014-02-20T15:36:56.337 回答
-1

将事件处理程序绑定到documentbody可能不是一个好主意,如果它已经存在于 DOM 中。

但是,如果元素是动态生成的(就像您的情况一样),那么您可能会将事件绑定到文档,然后维护您自己的容器、目标和单击事件处理程序堆栈,例如:

$(document).on("click", "#selector", function () {})

资料来源: 在 jQuery 中侦听文档级别的事件有什么缺点吗?

于 2014-02-20T10:06:30.427 回答