|
|
@@ -20,6 +20,7 @@
|
|
|
</div>
|
|
|
</template>
|
|
|
<script>
|
|
|
+import {verInViewport, horInViewport} from '../../../util/util.js';
|
|
|
export default {
|
|
|
name:'nut-lazycomponent',
|
|
|
props: {
|
|
|
@@ -59,9 +60,11 @@ export default {
|
|
|
// $slots.skeleton
|
|
|
//获取可视
|
|
|
let clientHeight = document.documentElement.clientHeight||document.body.clientHeight;
|
|
|
+ let clientWidth = document.documentElement.clientWidth||document.body.clientWidth;
|
|
|
// console.log($slots.skeleton)
|
|
|
return {
|
|
|
- // show:true
|
|
|
+ viewHeight:clientHeight,
|
|
|
+ viewWidth:clientWidth,
|
|
|
isInit:false,
|
|
|
io:null,
|
|
|
timer:null,
|
|
|
@@ -88,58 +91,27 @@ export default {
|
|
|
</svg>`
|
|
|
};
|
|
|
},
|
|
|
- methods: {
|
|
|
- add(){
|
|
|
+ methods: {
|
|
|
+ onScroll(){
|
|
|
+ let that = this;
|
|
|
+ window.addEventListener("scroll",that.listenElm)
|
|
|
},
|
|
|
- // render(){
|
|
|
- // let showchildrenArray= this.showChildrens;
|
|
|
- // let childrens = this.childrens;
|
|
|
- // let childrensLength = childrens.length;
|
|
|
- // let nextItem = this.nextItem +1;
|
|
|
- // if(!childrens[nextItem]){
|
|
|
- // console.log("没了")
|
|
|
- // return false;
|
|
|
- // }
|
|
|
- // this.nextItem = nextItem;
|
|
|
- // showchildrenArray.push(childrens[nextItem]);
|
|
|
- // console.log(nextItem,showchildrenArray.length)
|
|
|
- // this.showChildrens = showchildrenArray;
|
|
|
- // let that = this;
|
|
|
- // Vue.component('myslot',{
|
|
|
- // render:function(createElement){
|
|
|
- // return createElement('div',[showchildrenArray])
|
|
|
- // },
|
|
|
- // mounted(){
|
|
|
- // //渲染之后执行的函数
|
|
|
- // let elm = showchildrenArray[nextItem].elm;
|
|
|
- // let tempOffsetTop = elm.offsetTop + elm.clientHeight;
|
|
|
- // //滚动条高度
|
|
|
- // let scrollTop = document.documentElement.scrollTop||document.body.scrollTop;
|
|
|
-
|
|
|
- // if(tempOffsetTop-scrollTop<that.clientHeight){
|
|
|
-
|
|
|
- // that.offsetTopLastelm = tempOffsetTop;
|
|
|
- // that.render();
|
|
|
- // }
|
|
|
- // }
|
|
|
- // });
|
|
|
- // },
|
|
|
- // moveAndScroll(){
|
|
|
- // let that = this;
|
|
|
- // window.addEventListener("scroll", function (e) {
|
|
|
- // //滚动条高度
|
|
|
- // let scrollTop = document.documentElement.scrollTop||document.body.scrollTop;
|
|
|
- // //最后一个元素的高度
|
|
|
- // let offsetTopLastelm = that.offsetTopLastelm;
|
|
|
- // //可视窗口的
|
|
|
- // let clientHeight = that.clientHeight;
|
|
|
- // if(offsetTopLastelm + scrollTop > clientHeight){
|
|
|
- // // that.render();
|
|
|
- // }
|
|
|
- // // console.log(scrollTop,clientHeight,offsetTopLastelm)
|
|
|
- // })
|
|
|
- // },
|
|
|
- IntersectionObserver(entries){
|
|
|
+ listenElm(){
|
|
|
+ let that = this;
|
|
|
+ if(that.timer){
|
|
|
+ clearTimeout(that.timer);
|
|
|
+ }
|
|
|
+ that.timer = setTimeout(()=>{
|
|
|
+ if(that.NewIntersectionObserver({direction:that.direction})){
|
|
|
+ that.showComponent();
|
|
|
+ //移除监听
|
|
|
+ window.removeEventListener("scroll",that.listenElm)
|
|
|
+ }
|
|
|
+ },100)
|
|
|
+
|
|
|
+ },
|
|
|
+ //是否可见判断
|
|
|
+ Intersections(entries){
|
|
|
if(// 正在交叉
|
|
|
entries[0].isIntersecting ||
|
|
|
// 交叉率大于0
|
|
|
@@ -149,20 +121,19 @@ export default {
|
|
|
//this.io.disconnect();
|
|
|
}
|
|
|
},
|
|
|
+ //是否显示组件
|
|
|
showComponent(){
|
|
|
- // 此时说明骨架组件即将被切换
|
|
|
- // this.$emit('beforeInit')
|
|
|
- // this.$emit('before-init')
|
|
|
+ // 此时说明骨架组件即将被切换
|
|
|
// 此时可以准备加载懒加载组件的资源
|
|
|
this.loading = true
|
|
|
// 由于函数会在主线程中执行,加载懒加载组件非常耗时,容易卡顿
|
|
|
- // 所以在requestAnimationFrame回调中延后执行
|
|
|
-
|
|
|
+ // 所以在requestAnimationFrame回调中延后执行
|
|
|
this.requestAnimationFrame(() => {
|
|
|
this.isInit = true;
|
|
|
this.$emit('after-init',this.$el);
|
|
|
})
|
|
|
},
|
|
|
+ //定时
|
|
|
requestAnimationFrame (callback) {
|
|
|
// 防止等待太久没有执行回调
|
|
|
// 设置最大等待时间
|
|
|
@@ -174,41 +145,58 @@ export default {
|
|
|
}, this.maxWaitingTime)
|
|
|
// 兼容不支持requestAnimationFrame 的浏览器
|
|
|
return (window.requestAnimationFrame || ((callback) => setTimeout(callback, 1000 / 60)))(callback)
|
|
|
+ },
|
|
|
+ NewIntersectionObserver(options){
|
|
|
+ //判断是否可见
|
|
|
+ let isShow = null;
|
|
|
+ switch (options.direction) {
|
|
|
+ case 'vertical':
|
|
|
+ isShow = verInViewport(this.$el,this.viewHeight);
|
|
|
+ break;
|
|
|
+ case 'horizontal':
|
|
|
+ isShow = horInViewport(this.$el,this.viewWidth);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return isShow;
|
|
|
}
|
|
|
},
|
|
|
- created(){
|
|
|
- // this.render();
|
|
|
- // this.moveAndScroll() ;
|
|
|
-
|
|
|
-
|
|
|
- },
|
|
|
- mounted(){
|
|
|
- let rootMargin;
|
|
|
- switch (this.direction) {
|
|
|
- case 'vertical':
|
|
|
- rootMargin = `${this.threshold} 0px`
|
|
|
- break;
|
|
|
- case 'horizontal':
|
|
|
- rootMargin = `0px ${this.threshold}`
|
|
|
- break;
|
|
|
- };
|
|
|
- let $elm = this.$el;
|
|
|
- this.io = new IntersectionObserver(this.IntersectionObserver,{
|
|
|
- // 用于计算相交区域的根元素
|
|
|
- // 如果未提供,使用最上级文档的可见窗口
|
|
|
- root: this.viewport,
|
|
|
- // 同 margin,可以是 1、2、3、4 个值,允许时负值。
|
|
|
- // 如果显式指定了跟元素,该值可以使用百分比,即根元素大小的百分之多少。
|
|
|
- // 如果没指定根元素,使用百分比会出错。
|
|
|
- rootMargin,
|
|
|
- // 触发回调函数的临界值,用 0 ~ 1 的比率指定,也可以是一个数组。
|
|
|
- // 其值是被观测元素可视面积 / 总面积。
|
|
|
- // 当可视比率经过这个值的时候,回调函数就会被调用。
|
|
|
- threshold: [ 0, Number.MIN_VALUE, 0.01]
|
|
|
- });
|
|
|
- //对当前元素进行监听
|
|
|
- this.io.observe($elm);
|
|
|
- },
|
|
|
+ mounted(){
|
|
|
+ if(IntersectionObserver){
|
|
|
+ let rootMargin;
|
|
|
+ switch (this.direction) {
|
|
|
+ case 'vertical':
|
|
|
+ rootMargin = `${this.threshold} 0px`
|
|
|
+ break;
|
|
|
+ case 'horizontal':
|
|
|
+ rootMargin = `0px ${this.threshold}`
|
|
|
+ break;
|
|
|
+ };
|
|
|
+ let $elm = this.$el;
|
|
|
+ this.io = new IntersectionObserver(this.Intersections,{
|
|
|
+ // 用于计算相交区域的根元素
|
|
|
+ // 如果未提供,使用最上级文档的可见窗口
|
|
|
+ root: this.viewport,
|
|
|
+ // 同 margin,可以是 1、2、3、4 个值,允许时负值。
|
|
|
+ // 如果显式指定了跟元素,该值可以使用百分比,即根元素大小的百分之多少。
|
|
|
+ // 如果没指定根元素,使用百分比会出错。
|
|
|
+ rootMargin,
|
|
|
+ // 触发回调函数的临界值,用 0 ~ 1 的比率指定,也可以是一个数组。
|
|
|
+ // 其值是被观测元素可视面积 / 总面积。
|
|
|
+ // 当可视比率经过这个值的时候,回调函数就会被调用。
|
|
|
+ threshold: [ 0, Number.MIN_VALUE, 0.01]
|
|
|
+ });
|
|
|
+ //对当前元素进行监听
|
|
|
+ this.io.observe($elm);
|
|
|
+ } else{
|
|
|
+ //初始化
|
|
|
+ if(this.NewIntersectionObserver({direction:this.direction})){
|
|
|
+ this.showComponent()
|
|
|
+ } else {
|
|
|
+ //添加滚动监听
|
|
|
+ this.onScroll()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
beforeDestroy () {
|
|
|
if (this.io) {
|
|
|
this.io.unobserve(this.$el)
|