利用IntersectionObserver提升首屏性能

场景

首页展现内容很多,有时候一些元素开始不会出现在视口内,但是这些元素
组件可能内部会执行一些消耗性能的动画。这时候 我们可以使用IntersectionObserver 去实例出一个监听器 去监听一组元素,可以判定他是否出现在视口内,这时我们再去实现某些操作。也可以配合实现图片懒加载

上代码:

<template>
  <section class="contain" ref="myScroll">
    <div class="contain-item" v-for="item in list" :key="item.id">
      <div class="headImg" />
      <div class="comment">{
    
    {
    
     getContent(item) }}</div>
    </div>
  </section>
</template>

<script>
import {
    
     comment } from "@/comment/data.js";

export default {
    
    
  data() {
    
    
    return {
    
    
      list: comment,
      scrollTemp: null,
      isShow: false, //是否在视窗内
      dom: null,
      io: null,
    };
  },
  methods: {
    
    
    getContent(val) {
    
    
      let obj = JSON.parse(val.content);
      return obj.contentText || "暂无";
    },
    start() {
    
    
      //只有当滚动条未到底部并且元素进入了视口内 才进行滚动
      if (this.getScrollBottom() > 0 && this.isShow) {
    
    
        this.dom.scrollTop = this.dom.scrollTop + 1;
      }
      window.requestAnimationFrame(this.start);
    },
    getScrollBottom() {
    
    
      //获取滚动条到底部的距离
      let scrollTop = this.dom.scrollTop;
      let scrollHeight = this.dom.scrollHeight;
      let clientHeight = this.dom.clientHeight;
      let scrollBottom = scrollHeight - scrollTop - clientHeight;
      return scrollBottom;
    },
  },
  computed: {
    
    },
  mounted() {
    
    
    this.dom = this.$refs.myScroll;
    this.io = new IntersectionObserver((entries) => {
    
    
      entries.forEach((item) => {
    
    
        if (item.target === this.dom) {
    
    
          if (item.isIntersecting) {
    
    
            //进入可视区
            this.isShow = true;
          } else {
    
    
            //不在可视区
            this.isShow = false;
          }
        }
      });
    });
    //对指定元素进行监听
    this.io.observe(this.dom);
    this.start();
  },
  beforeDestroy() {
    
    
    //销毁时解绑监听事件
    this.io && this.io.disconnect();
  },
};
</script>

<style scoped lang="scss">
p {
    
    
  margin: 0;
  padding: 0;
}
.contain {
    
    
  width: 100%;
  height: 300px;
  overflow-y: auto;
  font-size: 14px;
  background: #efefef;
  .contain-item {
    
    
    width: 100%;
    overflow: hidden;
    .headImg {
    
    
      margin-top: 10px;
      float: left;
      left: 0;
      width: 25px;
      height: 25px;
      border-radius: 50%;
      background-image: url("@/assets/logo.png");
      background-size: cover;
      margin-left: 30px;
    }
    .comment {
    
    
      float: right;
      text-align: left;
      padding: 4px;
      margin: 10px 30px 10px 0;
      border-radius: 4px;
      right: 12px;
      background: #fff;
      line-height: 25px;
      width: 70%;
      word-break: break-all;
      text-overflow: ellipsis;
      display: -webkit-box; /** 对象作为伸缩盒子模型显示 **/
      -webkit-box-orient: vertical; /** 设置或检索伸缩盒对象的子元素的排列方式 **/
      -webkit-line-clamp: 2; /** 显示的行数 **/
      overflow: hidden; /** 隐藏超出的内容 **/
    }
  }
}
</style>

说明

1.在mounted后 创建IntersectionObserver 实例对象,对指定的元素进行监听
2.在beforeDestroy钩子中记得解绑监听事件

Guess you like

Origin blog.csdn.net/weixin_45485922/article/details/124826720