UNPKG

mobile-pull-to-refresh

Version:
100 lines (81 loc) 2.53 kB
import ontouchpan from './ontouchpan' export default function(opts) { opts = Object.assign({ // https://bugs.chromium.org/p/chromium/issues/detail?id=766938 scrollable: document.body, threshold: 150, onStateChange() { /* noop */ } }, opts) const { container, scrollable, threshold, refresh, onStateChange, animates } = opts let distance, offset, state // state: pulling, aborting, reached, refreshing, restoring function addClass(cls) { container.classList.add('pull-to-refresh--' + cls) } function removeClass(cls) { container.classList.remove('pull-to-refresh--' + cls) } function scrollTop() { if (!scrollable || [window, document, document.body, document.documentElement].includes(scrollable)) { return document.documentElement.scrollTop || document.body.scrollTop } else { return scrollable.scrollTop } } return ontouchpan({ element: container, onpanmove(e) { let d = e.deltaY if (scrollTop() > 0 || d < 0 && !state || state in { aborting: 1, refreshing: 1, restoring: 1 }) return if (e.cancelable) { e.preventDefault() } if (distance == null) { offset = d state = 'pulling' addClass(state) onStateChange(state, opts) } d = d - offset if (d < 0) d = 0 distance = d if (d >= threshold && state !== 'reached' || d < threshold && state !== 'pulling') { removeClass(state) state = state === 'reached' ? 'pulling' : 'reached' addClass(state) onStateChange(state, opts) } animates.pulling(d, opts) }, onpanend() { if (state == null) return if (state === 'pulling') { removeClass(state) state = 'aborting' onStateChange(state) addClass(state) animates.aborting(opts).then(() => { removeClass(state) distance = state = offset = null onStateChange(state) }) } else if (state === 'reached') { removeClass(state) state = 'refreshing' addClass(state) onStateChange(state, opts) animates.refreshing(opts) refresh().then(() => { removeClass(state) state = 'restoring' addClass(state) onStateChange(state) animates.restoring(opts).then(() => { removeClass(state) distance = state = offset = null onStateChange(state) }) }) } } }) }