无限滚动更新后附加事件处理程序

时间:2012-10-10 12:43:49

标签: javascript jquery infinite-scroll

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

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

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

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

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

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

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

我在这里做错了什么?

我的事件监听器是否写得不正确?

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

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

2 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:0)

如果有人有兴趣在没有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
  }
})