UNPKG

@webcreate/infinite-ajax-scroll

Version:

Turn your existing pagination into infinite scrolling pages with ease

120 lines (95 loc) 2.7 kB
import extend from "extend"; import Assert from "./assert"; import $ from "tealight"; import * as Events from "./events"; const defaults = { element: undefined, when: (pageIndex) => true, show: (element) => { element.style.opacity = '1'; }, hide: (element) => { element.style.opacity = '0'; } }; function expand(options) { if (typeof options === 'string' || typeof options === 'function' || (typeof options === 'object' && options.nodeType === Node.ELEMENT_NODE)) { options = { element: options, } } if (typeof options.element === 'function') { options.element = options.element(); } // expand array to a function, e.g.: // [0, 1, 2] -> function(pageIndex) { /* return true when pageIndex in [0, 1, 2] */ } if (options.when && Array.isArray(options.when)) { let when = options.when; options.when = function(pageIndex) { return when.indexOf(pageIndex) !== -1; } } return options; } export default class Trigger { constructor(ias, options) { // no trigger wanted if (options === false) { return; } this.ias = ias; this.options = extend({}, defaults, expand(options)); if (this.options.element !== undefined) { Assert.singleElement(this.options.element, 'trigger.element'); } this.element = $(this.options.element)[0]; // @todo should we really cache this? this.hideFn = this.options.hide; this.showFn = this.options.show; this.voter = this.options.when; this.showing = undefined; this.enabled = undefined; ias.on(Events.BINDED, this.bind.bind(this)); ias.on(Events.UNBINDED, this.unbind.bind(this)); ias.on(Events.HIT, this.hit.bind(this)); ias.on(Events.NEXT, (e) => this.ias.once(Events.APPENDED, () => this.update(e.pageIndex))); } bind() { this.hide(); this.update(this.ias.pageIndex); this.element.addEventListener('click', this.clickHandler.bind(this)); } unbind() { this.element.removeEventListener('click', this.clickHandler.bind(this)); } clickHandler() { this.hide().then(this.ias.next.bind(this.ias)); } update(pageIndex) { this.enabled = this.voter(pageIndex); if (this.enabled) { this.ias.disableLoadOnScroll(); } else { this.ias.enableLoadOnScroll(); } } hit() { if (!this.enabled) { return; } this.show(); } show() { if (this.showing) { return; } this.showing = true; return Promise.resolve(this.showFn(this.element)); } hide() { if (!this.showing && this.showing !== undefined) { return; } this.showing = false; return Promise.resolve(this.hideFn(this.element)); } }