Skip to content

Instantly share code, notes, and snippets.

@nigeltiany
Created June 19, 2017 22:42
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save nigeltiany/dfdfb4d47027c3a95f19c048700f8828 to your computer and use it in GitHub Desktop.
Fixing Quasar Infinite Scroll Component
<template>
<div class="q-infinite-scroll">
<div ref="content" class="q-infinite-scroll-content">
<slot></slot>
</div>
<div class="q-infinite-scroll-message" v-show="fetching">
<slot name="message"></slot>
</div>
</div>
</template>
<script>
// import { height, offset } from '../../quasar/quasar.es6'
// import { debounce } from '../../quasar/quasar.es6'
// import { getScrollTarget } from '../../quasar/quasar.es6'
function viewport () {
let
e = window,
a = 'inner';
if (!('innerWidth' in window)) {
a = 'client';
e = document.documentElement || document.body;
}
return {
width: e[a + 'Width'],
height: e[a + 'Height']
}
}
function height (el) {
if (el === window) {
return viewport().height
}
return parseFloat(window.getComputedStyle(el).getPropertyValue('height'), 10)
}
let now = Date.now;
function debounce (fn, wait = 250, immediate) {
let
timeout, params, context, timestamp, result,
later = () => {
let last = now() - timestamp;
if (last < wait && last >= 0) {
timeout = setTimeout(later, wait - last);
}
else {
timeout = null;
if (!immediate) {
result = fn.apply(context, params);
if (!timeout) {
context = params = null;
}
}
}
};
return function (...args) {
var callNow = immediate && !timeout;
context = this;
timestamp = now();
params = args;
if (!timeout) {
timeout = setTimeout(later, wait);
}
if (callNow) {
result = fn.apply(context, args);
context = params = null;
}
return result
}
}
function getScrollTarget (el) {
return el.closest('.layout-view,.scroll') || window
}
function offset (el) {
if (el === window) {
return {top: 0, left: 0}
}
let {top, left} = el.getBoundingClientRect();
return {top, left}
}
export default {
name: 'fixInfiniteScroll',
props: {
handler: {
type: Function,
required: true
},
inline: Boolean,
offset: {
type: Number,
default: 0
}
},
data () {
return {
index: 0,
fetching: false,
working: true
}
},
methods: {
poll () {
if (this.fetching || !this.working) {
return
}
let
containerHeight = height(this.scrollContainer),
containerBottom = offset(this.scrollContainer).top + containerHeight,
triggerPosition = offset(this.element).top + height(this.element) - (this.offset || containerHeight)
if (triggerPosition < containerBottom) {
this.loadMore()
}
},
loadMore () {
if (this.fetching || !this.working) {
return
}
this.index+=2
this.fetching = true
this.handler("quasar", "vuejs")
},
reset () {
this.index = 0
},
resume () {
this.working = true
this.scrollContainer.addEventListener('scroll', this.poll)
this.poll()
},
stop () {
this.working = false
this.fetching = false
this.scrollContainer.removeEventListener('scroll', this.poll)
}
},
mounted () {
this.$nextTick(() => {
this.poll = debounce(this.poll, 50)
this.element = this.$refs.content
this.scrollContainer = this.inline ? this.$el : getScrollTarget(this.$el)
if (this.working) {
this.scrollContainer.addEventListener('scroll', this.poll)
}
this.poll()
})
},
beforeDestroy () {
this.scrollContainer.removeEventListener('scroll', this.poll)
}
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment