waypoints
waypoints copied to clipboard
Waypoints fire more than once when I reach and load new content
Check out my page: www.picturepunches.com
I load waypoint once the page is loaded and every time the user reach to the bottom. I want waypoint to excute once everytime it reaches a point. But the problem is that it execute twice once new content in loaded via ajax.
Can anyone help?
I face the same issue. Either Ajax content doesn't work or it works more than once, when the $items code is changed a bit.
This problem also bothered me for a long time, and then I finally to solve it successfully. I will record my method for your reference:
Before set the option, the height of the container must be given to prevent the position from running away
const container = document.querySelector('.infinite-container');
let containerHight;
container.style.height = container.clientHeight + 'px';
$(window).on('load', function () {
infiniteExample();
});
function infiniteExample() {
const infinite = new Waypoint.Infinite({
element: $('.infinite-container')[0],
onBeforePageLoad: function () {
// we use css to change height auto if user resize window, and don't remove container.style.height
if (container.classList.contains('height-auto')) container.classList.remove('height-auto');
containerHight = container.clientHeight;
container.style.height = containerHight + 'px';
},
onAfterPageLoad: function ($items) {
//- get new page height
let newLoadHight = handleLoadH($items);
container.style.height = containerHight + newLoadHight + 'px';
//- if last page
if ($items.prevObject[2].className != 'infinite-more-link') {
container.classList.add('is-done');
}
}
});
};
// wirte a css .height-auto {height:auto!important}
window.addEventListener('resize', function () {
container.classList.add('height-auto');
});
// function get new page height:
const handleLoadH = function (obj) {
// console to check data
//- let data = JSON.stringify(obj);
let data = [];
obj.each(function (item) {
return data.push(obj[item].clientHeight);
});
//- console.log(data);
//- I'm load 6 item in one page
//- 3 item in a row on PC
//- 2 item in a row on Table
//- 1 item in a row on mobile
if (window.innerWidth >= 992) {
let row1 = data.slice(0, 3);
let row2 = data.slice(3, 6);
return Number(choseBig(row1)) + Number(choseBig(row2));
} else if (window.innerWidth <= 991 && window.innerWidth >= 768) {
let row1 = data.slice(0, 2);
let row2 = data.slice(2, 4);
let row3 = data.slice(4, 6);
return Number(choseBig(row1)) + Number(choseBig(row2)) + Number(choseBig(row3));
} else {
return data.reduce((a, b) => a + b, 0);
}
};
function choseBig(arr) {
return arr.sort((a, b) => b - a).slice(0, 1);
};
Then modify infinite.js
/* Private */
Infinite.prototype.setupHandler = function () {
this.options.handler = $.proxy(function () {
this.options.onBeforePageLoad()
this.destroy()
this.$container.addClass(this.options.loadingClass)
$.get($(this.options.more).attr('href'), $.proxy(function (data) {
...
if (!$newMore.length) {
$newMore = $data.filter(this.options.more)
}
// change it !!
this.options.onAfterPageLoad($items)
//
if ($newMore.length) {
this.$more.replaceWith($newMore)
this.$more = $newMore
this.waypoint = new Waypoint(this.options)
}
else {
this.$more.remove()
}
// this.options.onAfterPageLoad($items)
}, this))
}, this)
}
done, enjoy it
In 2022, there maybe have other better lazyload library, but the classic is undefeated