|
1 |
| -<template></template> |
| 1 | +<template> |
| 2 | + <div class="infinite-loading-container" |
| 3 | + :class="{ |
| 4 | + hidden: !isLoading |
| 5 | + }"> |
| 6 | + <i class="icon-loading"></i> |
| 7 | + </div> |
| 8 | +</template> |
2 | 9 | <script>
|
3 |
| - export default {}; |
| 10 | + let scrollParent; |
| 11 | + let scrollHandler; |
| 12 | +
|
| 13 | + /** |
| 14 | + * get the first scroll parent of an element |
| 15 | + * @param {DOM} elm the element which find scorll parent |
| 16 | + * @return {DOM} the first scroll parent |
| 17 | + */ |
| 18 | + function getScrollParent(elm) { |
| 19 | + if (elm.tagName === 'BODY') { |
| 20 | + return window; |
| 21 | + } else if (['scroll', 'auto'].indexOf(getComputedStyle(elm).overflowY) > -1) { |
| 22 | + return elm; |
| 23 | + } |
| 24 | + return getScrollParent(elm.parentNode); |
| 25 | + } |
| 26 | +
|
| 27 | + /** |
| 28 | + * get current distance from footer |
| 29 | + * @param {DOM} elm scroll element |
| 30 | + * @return {Number} distance |
| 31 | + */ |
| 32 | + function getCurrentDistance(elm) { |
| 33 | + const innerHeight = elm === window |
| 34 | + ? window.innerHeight |
| 35 | + : parseInt(getComputedStyle(elm).height, 10); |
| 36 | + const scrollHeight = elm === window |
| 37 | + ? document.body.scrollHeight |
| 38 | + : elm.scrollHeight; |
| 39 | +
|
| 40 | + return scrollHeight - innerHeight - (elm.scrollTop || elm.pageYOffset); |
| 41 | + } |
| 42 | +
|
| 43 | + export default { |
| 44 | + data() { |
| 45 | + return { |
| 46 | + isLoading: false, |
| 47 | + }; |
| 48 | + }, |
| 49 | + props: { |
| 50 | + distance: Number, |
| 51 | + onInfinite: Function, |
| 52 | + }, |
| 53 | + ready() { |
| 54 | + if (this.distance === undefined) { |
| 55 | + this.$set('distance', 50); |
| 56 | + } |
| 57 | +
|
| 58 | + scrollParent = getScrollParent(this.$el); |
| 59 | +
|
| 60 | + scrollHandler = function scrollHandlerOriginal() { |
| 61 | + const currentDistance = getCurrentDistance(scrollParent); |
| 62 | + if (!this.isLoading) { |
| 63 | + if (currentDistance <= this.distance) { |
| 64 | + this.isLoading = true; |
| 65 | + if (this.onInfinite) { |
| 66 | + this.onInfinite.call(); |
| 67 | + } |
| 68 | + } |
| 69 | + } |
| 70 | + }.bind(this); |
| 71 | +
|
| 72 | + setTimeout(scrollHandler, 1); |
| 73 | + scrollParent.addEventListener('scroll', scrollHandler); |
| 74 | + }, |
| 75 | + events: { |
| 76 | + // Hide the loading icon when data was loaded |
| 77 | + '$InfiniteLoading:loaded'() { |
| 78 | + this.isLoading = false; |
| 79 | + }, |
| 80 | + }, |
| 81 | + destroyed() { |
| 82 | + scrollParent.removeEventListener('scroll', scrollHandler); |
| 83 | + }, |
| 84 | + }; |
4 | 85 | </script>
|
| 86 | +<style lang="less"> |
| 87 | + @font-face {font-family: "vue-infinite-loading"; |
| 88 | + src: url('../assets/vue-infinite-loading.eot?t=1462930749'); /* IE9*/ |
| 89 | + src: url('../assets/vue-infinite-loading.woff?t=1462930749') format('woff'), /* chrome, firefox */ |
| 90 | + url('../assets/vue-infinite-loading.ttf?t=1462930749') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/ |
| 91 | + url('../assets/vue-infinite-loading.svg?t=1462930749#vue-infinite-loading') format('svg'); /* iOS 4.1- */ |
| 92 | + } |
| 93 | + .icon-loading:before { |
| 94 | + content: "\e600"; |
| 95 | + font-family:"vue-infinite-loading" !important; |
| 96 | + font-style:normal; |
| 97 | + -webkit-font-smoothing: antialiased; |
| 98 | + -webkit-text-stroke-width: 0.2px; |
| 99 | + -moz-osx-font-smoothing: grayscale; |
| 100 | + } |
| 101 | +
|
| 102 | + .infinite-loading-container{ |
| 103 | + clear: both; |
| 104 | + padding: 15px 0; |
| 105 | + min-height: 40px; |
| 106 | + text-align: center; |
| 107 | + *[class^=icon-]{ |
| 108 | + @size: 30px; |
| 109 | + display: inline-block; |
| 110 | + width: @size; |
| 111 | + height: @size; |
| 112 | + font-size: @size; |
| 113 | + line-height: @size; |
| 114 | + color: #999; |
| 115 | + animation: ease loading 1.5s infinite; |
| 116 | + } |
| 117 | + &.hidden{ |
| 118 | + display: none; |
| 119 | + } |
| 120 | + } |
| 121 | +
|
| 122 | + @keyframes loading { |
| 123 | + 0%{ |
| 124 | + transform: rotate(-38deg); |
| 125 | + } |
| 126 | + 100%{ |
| 127 | + transform: rotate(322deg); |
| 128 | + } |
| 129 | + } |
| 130 | +</style> |
0 commit comments