There's no load, just a way to tell if the scroll bar has reached the bottom of the browser If it arrives, the event will be triggered. If it arrives, it will not be handled.
The calculation formula is simple: the bottom is equal to (0) = the height of the scroll bar - the distance between the top of the scroll bar and the visible height. The result is zero anyway.
I. get scroll bar position
class Scroll { static get top() { return Math.max(document.documentElement.scrollTop || document.body.scrollTop); } static get clientHeight() { return Math.max(document.documentElement.clientHeight || document.body.clientHeight); } static get clientWidth() { return Math.max(document.documentElement.clientWidth || document.body.clientWidth); } static get height() { return Math.max(document.documentElement.scrollHeight || document.body.scrollHeight); } static get width() { return Math.max(document.documentElement.scrollWidth || document.body.scrollWidth); } static get bottom() { return Scroll.height - Scroll.clientHeight - Scroll.top; } }
2. Bind scrolling events to the root node
vue binds the scrollbar event to the body element, the real TMD grass egg. Events are bound up. The fuck is that they don't trigger events. I don't know what the hell is wrong.
Finally, the root node HTML is bound to scroll events directly.
const on = (function () { if (document.addEventListener) { return function (element, event, handler) { if (element && event && handler) { element.addEventListener(event, handler, false); } }; } else { return function (element, event, handler) { if (element && event && handler) { element.attachEvent('on' + event, handler); } }; } })();
III. register global instructions
/** * Reduce the frequency of event execution */ const downsampler = (function () { let result = null; return function (time, func) { if (!result) { result = setTimeout(function () { func(); result = null; }, time); } } })();
Vue.directive("infinite-scroll", { bind(el, binding, vnode) { on(window, 'scroll', function () { if (typeof binding.value === "function" && Scroll.bottom <= 50) { // Trigger if less than 50 downsampler(50, binding.value); // Reduce trigger frequency } }) } });
IV. examples:
<div class="app" v-infinite-scroll="coupon"> <template v-for="item in goods"> <p>{{item}}</p> </template> </div>
let v = new Vue({ el: ".app", data(){ return { goods:[] } }, methods: { coupon() { this.goods.push("You ha ha") } } })
Demo address: http://whnba.gitee.io/tkspa/