需求:页面有一堆图表、需要滚动到图表时、再加载出来这个图表、
思路:没找到合适的插件、只能自己手撸一个、直接放到混入里就行、主要就是判断元素距离底部的距离和可视区域内容的高度进行对比即可
/**
* 判断某个原生DOM元素是否已经在屏幕可见区内出现过
* @param {*} el 原生DOM元素
*/
const isElementNotInViewport = function (el) {
let rect = el.getBoundingClientRect();
return rect.bottom <= (window.innerHeight || document.documentElement.clientHeight)
};
export { isElementNotInViewport };
注意、这个方法是判断内容已经出现在可视区域、也可能划上去了、所以是出现过、只需要判断元素底部的距离小于可视区域内容的高度即可、如果只需要判断可视区域、那么就需要加上元素距离顶部的距离top
混入中的完整代码 mixins.js
import { isElementNotInViewport } from "libs/public.js";
export default {
data() {
return {
isLoading: false,
oldScrollTop: 0, //记录上一次滚动结束后的滚动距离
scrollTop: 0, // 记录当前的滚动距离
}
},
mounted() {
// 图表懒加载
this.$nextTick(() => {
let timer;
const that = this;
const valuePage = document.getElementById("id名称");
valuePage .addEventListener("scroll", (e) => {
this.scrollTop = valuePage .scrollTop;
// 判断是否向下滚动
if (this.scrollTop - this.oldScrollTop > 0) {
for (let k = 1; k <= this.echartsNum; k++) {
if (!this[`show${k}`]) {
this.isLoading = true;
}
}
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
that.handleScroll();
}, 200);
}
});
this.handleScroll();
});
},
watch: {
scrollTop(newValue, oldValue) {
const valuePage = document.getElementById("id名称");
setTimeout(() => {
if (newValue === valuePage .scrollTop) {
// 滚动结束
setTimeout(() => {
this.isLoading = false;
}, 1000);
this.oldScrollTop = newValue; //每次滚动结束后都要给oldScrollTop赋值
}
}, 20); //必须使用延时器,否则每次newValue和滚动条scrollY都相等,无法判断,20ms刚好大于watch的侦听周期,故延时20ms
if (this.oldScrollTop == oldValue) {
//滚动开始 oldScrollTop与oldValue相等
}
},
},
methods: {
handleScroll() {
for (let k = 1; k <= this.echartsNum; k++) {
let viewDom = document.getElementById(`show${k}`);
if (isElementNotInViewport(viewDom)) {
this[`show${k}`] = true;
}
}
}
}
}
页面使用
<template>
<div>
<Card id="show1">
<div v-if="show1">
内容1234567890
</div>
</Card>
<Card id="show2">
<div v-if="show2">
内容1234567890
</div>
</Card>
<Card id="show3">
<div v-if="show3">
内容1234567890
</div>
</Card>
......................
</div>
</template>
<script>
import mixin from "libs/mixins";
export default {
mixins: [mixin],
data() {
return {
show1: false,
show2: false,
show3: false,
echartsNum: 3, // 需要滚动加载的图表数量
}
}
}
</script>
这里使用了id 、没用ref的原因是报错了、排查半天没找到原因、哈哈哈!
写的一般、欢迎大佬们指正!