| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- <template>
- <div class="nut-infiniteloading" ref="scroller" @touchstart="touchStartHandle($event)" @touchmove="touchMoveHandle($event)">
- <slot></slot>
- <div class="load-more">
- <div class="bottom-tips">
- <template v-if="isLoading"> <i class="loading-hint"></i><span class="loading-txt">加载中...</span> </template>
- <span v-else-if="!hasMore" class="tips-txt">{{ unloadMoreTxt }}</span>
- </div>
- </div>
- </div>
- </template>
- <script>
- export default {
- name: 'nut-infiniteloading',
- props: {
- hasMore: {
- type: Boolean,
- default: true,
- },
- isLoading: {
- type: Boolean,
- default: false,
- },
- threshold: {
- type: Number,
- default: 200,
- },
- useWindow: {
- type: Boolean,
- default: true,
- },
- useCapture: {
- type: Boolean,
- default: false,
- },
- isShowMod: {
- type: Boolean,
- default: false,
- },
- unloadMoreTxt: {
- type: String,
- default: '哎呀,这里是底部了啦',
- },
- scrollChange: {
- type: Function,
- },
- containerId: {
- type: String,
- default: '',
- },
- },
- data() {
- return {
- startX: 0,
- startY: 0,
- diffX: 0,
- diffY: 0,
- beforeScrollTop: 0,
- };
- },
- mounted: function () {
- const parentElement = this.getParentElement(this.$el);
- let scrollEl = window;
- if (this.useWindow === false) {
- scrollEl = parentElement;
- }
- this.scrollEl = scrollEl;
- this.scrollListener();
- },
- methods: {
- touchStartHandle(e) {
- try {
- this.startX = Number(e.changedTouches[0].pageX);
- this.startY = Number(e.changedTouches[0].pageY);
- } catch (e) {
- console.log(e.message);
- }
- },
- touchMoveHandle(e) {
- let endX = Number(e.changedTouches[0].pageX);
- let endY = Number(e.changedTouches[0].pageY);
- this.diffX = endX - this.startX;
- this.diffY = endY - this.startY;
- },
- getParentElement(el) {
- if (this.containerId) {
- return document.querySelector(`#${this.containerId}`);
- }
- return el && el.parentNode;
- },
- scrollListener() {
- this.scrollEl.addEventListener('scroll', this.handleScroll, this.useCapture);
- window.addEventListener('resize', this.handleScroll, this.useCapture);
- },
- requestAniFrame() {
- return (
- window.requestAnimationFrame ||
- window.webkitRequestAnimationFrame ||
- window.mozRequestAnimationFrame ||
- function (callback) {
- window.setTimeout(callback, 1000 / 60);
- }
- );
- },
- handleScroll() {
- this.requestAniFrame()(() => {
- if (!this.isScrollAtBottom() || !this.hasMore || this.isLoading || !this.isShowMod) {
- return false;
- } else {
- this.$emit('loadmore');
- }
- });
- },
- calculateTopPosition(el) {
- if (!el) {
- return 0;
- }
- return el.offsetTop + this.calculateTopPosition(el.offsetParent);
- },
- getWindowScrollTop() {
- return window.pageYOffset !== undefined
- ? window.pageYOffset
- : (document.documentElement || document.body.parentNode || document.body).scrollTop;
- },
- isScrollAtBottom() {
- let offsetDistance;
- let resScrollTop = 0;
- const windowScrollTop = this.getWindowScrollTop();
- if (this.useWindow) {
- offsetDistance = this.calculateTopPosition(this.$refs.scroller) + this.$refs.scroller.offsetHeight - windowScrollTop - window.innerHeight;
- } else {
- const { scrollHeight, clientHeight, scrollTop } = this.scrollEl;
- offsetDistance = scrollHeight - clientHeight - scrollTop;
- resScrollTop = scrollTop;
- }
- this.$emit('scrollChange', this.useWindow ? windowScrollTop : resScrollTop);
- // 保证是往下滑动的
- let beforeScrollTop = this.beforeScrollTop;
- this.beforeScrollTop = windowScrollTop;
- return offsetDistance <= this.threshold && windowScrollTop >= this.beforeScrollTop;
- },
- },
- activated() {
- if (this.keepAlive) {
- this.keepAlive = false;
- this.scrollListener();
- }
- },
- deactivated() {
- this.keepAlive = true;
- this.scrollEl.removeEventListener('scroll', this.handleScroll, this.useCapture);
- window.removeEventListener('resize', this.handleScroll, this.useCapture);
- },
- destroyed() {
- this.scrollEl.removeEventListener('scroll', this.handleScroll, this.useCapture);
- window.removeEventListener('resize', this.handleScroll, this.useCapture);
- },
- };
- </script>
|