UNPKG

quasar-framework

Version:

Build responsive SPA, SSR, PWA, Hybrid Mobile Apps and Electron apps, all simultaneously using the same codebase

98 lines (89 loc) 2.73 kB
import debounce from '../utils/debounce.js' import { getScrollPosition, setScrollPosition, getScrollTarget } from '../utils/scroll.js' import { listenOpts } from '../utils/event.js' function updateBinding (el, { value, modifiers }) { const ctx = el.__qbacktotop if (!value) { ctx.update() return } if (typeof value === 'number') { ctx.offset = value ctx.update() return } if (value && Object(value) !== value) { console.error('v-back-to-top requires an object {offset, duration} as parameter', el) return } if (value.offset) { if (typeof value.offset !== 'number') { console.error('v-back-to-top requires a number as offset', el) return } ctx.offset = value.offset } if (value.duration) { if (typeof value.duration !== 'number') { console.error('v-back-to-top requires a number as duration', el) return } ctx.duration = value.duration } ctx.update() } export default { name: 'back-to-top', bind (el) { const ctx = { offset: 200, duration: 300, updateNow: () => { const trigger = getScrollPosition(ctx.scrollTarget) <= ctx.offset if (trigger !== el.classList.contains('hidden')) { el.classList[trigger ? 'add' : 'remove']('hidden') } }, goToTop () { setScrollPosition(ctx.scrollTarget, 0, ctx.animate ? ctx.duration : 0) }, goToTopKey (evt) { if (evt.keyCode === 13) { setScrollPosition(ctx.scrollTarget, 0, ctx.animate ? ctx.duration : 0) } } } ctx.update = debounce(ctx.updateNow, 25) el.classList.add('hidden') el.__qbacktotop = ctx }, inserted (el, binding) { const ctx = el.__qbacktotop ctx.scrollTarget = getScrollTarget(el) ctx.animate = binding.modifiers.animate updateBinding(el, binding) ctx.scrollTarget.addEventListener('scroll', ctx.update, listenOpts.passive) window.addEventListener('resize', ctx.update, listenOpts.passive) el.addEventListener('click', ctx.goToTop) el.addEventListener('keyup', ctx.goToTopKey) }, update (el, binding) { if (JSON.stringify(binding.oldValue) !== JSON.stringify(binding.value)) { updateBinding(el, binding) } else { setTimeout(() => { el.__qbacktotop && el.__qbacktotop.updateNow() }, 0) } }, unbind (el) { const ctx = el.__qbacktotop if (!ctx) { return } ctx.scrollTarget.removeEventListener('scroll', ctx.update, listenOpts.passive) window.removeEventListener('resize', ctx.update, listenOpts.passive) el.removeEventListener('click', ctx.goToTop) el.removeEventListener('keyup', ctx.goToTopKey) delete el.__qbacktotop } }