【问题标题】:Attaching Event Handlers after Infinite Scroll Update无限滚动更新后附加事件处理程序
【发布时间】:2012-10-10 12:43:48
【问题描述】:

我正在使用无限滚动插件http://www.infinite-scroll.com/infinite-scroll-jquery-plugin/ 来加载页面内容。

我有一个 jQuery 事件监听器,例如:

$('.like-action').on('click',
    function(event){
      likeComment($(this)); 
      event.preventDefault();
});

该 get 已加载到 $(document).ready。但是,当使用 infinitescroll 加载新内容时,事件侦听器不适用于新内容/不可用。因此,我创建了一个在infinitescroll 的回调上调用的函数(当所有内容都已加载时)。函数:

function afterUpdate(){
$('.like-action').on('click',function(event){
      likeComment($(this)); 
      event.preventDefault();
});}

然而,最终发生的情况是,当单击具有.like-action class 的链接时,对于旧内容(已加载),likeComment 函数被调用,但新内容已加载多次 + 原始内容$(document).ready.

例如:内容在页面加载时加载。链接在点击时执行likeComment1。如果您单击与以前相同的链接,向下滚动并加载(和回调)新内容后,likeComment 将执行两次。等等等等。

我在这里做错了什么?

我的事件监听器写错了吗?

有没有办法编写一个侦听器,该侦听器自动适用于DOM 中的所有元素,即使它们在页面加载时不存在?

或者,有没有办法只在无限滚动刚刚加载的元素上注册 .on(所以没有重复)?

【问题讨论】:

    标签: javascript jquery infinite-scroll


    【解决方案1】:

    更改on() 的用法以传递选择器,它将使用事件委托,从而使点击处理程序也适用于所有未来的元素:

    $('#someContainer').on('click', '.like-action', function (event){
        likeComment($(this)); 
        event.preventDefault();
    });
    

    这将防止您的点击处理程序需要再次添加,从而解决您将它们多次添加到旧元素的问题。

    这假设您当前和未来的所有.like-action 元素都将包含在#someContainer 中。

    编辑:响应您的评论,您不能像这样委派插件初始化。你可以做的是:当你初始化一个元素时,也给它添加一个类:

    $('.profilecard').hovercard().addClass('initialized');
    

    然后在你的回调中,当你需要初始化新的时,跳过任何已经有该类的东西:

    function afterUpdate(){ 
        $('.profilecard:not(".initialized")').hovercard();
    }
    

    【讨论】:

    • jbabey,这对于以下内容是如何工作的:$(document).ready(function() {$( '.profilecard' ).hovercard();}); 因为从技术上讲这不是附加事件处理程序?
    • jbabey,刚刚将更改添加到 .on 中,它就像冠军一样工作!谢谢!好的,所以事件处理程序和添加插件初始化之间的区别是因为插件被“附加”到 DOM 元素?那么,初始化的类是用来检查是否已经被附加了?
    • this page 将有助于解释为什么它适用于事件(delegateon 相同,只是更旧)。插件的初始化不会像事件一样传播 DOM,因此它不能被委托。
    【解决方案2】:

    如果有人有兴趣在不使用 jQuery 的情况下执行此操作,这里有一篇很棒的帖子 - https://elliotekj.com/2016/11/05/jquery-to-pure-js-event-listeners-on-dynamically-created-elements/

    基本示例:

    document.querySelector(staticParent).addEventListener(eventName, function (event) {
      if (event.target.classList.contains(dynamicChildSelector)) {
        // Do something
      }
    })
    

    工作示例:

    document.querySelector('.feed').addEventListener('click', function (event) {
      if (event.target.classList.contains('feed-item')) {
        // Do something
      }
    })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-01
      相关资源
      最近更新 更多