IntersectionObserver 实现上/下无限滚动

无限滚动

很多人以为无限滚动,就是只是触底加载,但是加载到一定长度,页面会爆炸!!

真正的无限加载是真正的无限!
页面仅渲染可见的元素,对不可见的不占用页面节点,才可实现真正的无限滚动。

无限滚动-1

无限滚动-1

无限滚动-2
无限滚动-2

对 IntersectionObserver 监听元素可见的思考

可以实现:

1. 触顶:移除下面,渲染上面,解除顶部占位
2. 触底:移除上面,渲染下面,增加顶部占位

实现的技巧:

1. 只修改一个变量达到效果。
2. 用计算属性动态得出该渲染什么。
3. `threshold`使用`0.0000001`,判断`intersectionRatio > 0.01`比较稳(能保证真正的可见)。
4. end元素,向上相对定位,实现预加载(提前触底)。

实现代码:

视图层

<template>
  <div class="infinity-sroll-container">
    <div :style="{ paddingTop: (showStart - 1) * 200 + 'px' }">
      <div data-site="start" ref="start"></div>
      <div
        class="item"
        v-for="(n, i) in showList"
        :key="i"
        :style="{backgroundColor: colors[n % 10]}"
      >
        {{n}}
      </div>
      <div class="end" data-site="end" ref="end"></div>
    </div>
  </div>
</template>

逻辑层

export default {
  data() {
    return {
      showStart: 1,
      colors: [
        '#CCCC33',
        '#CCCCCC',
        '#FFFFCC',
        '#0099FF',
        '#33CC99',
        '#FFFFFF',
        '#ff9900',
        '#99CC33',
        '#99CCFF',
        '#CC9999'
      ]
    };
  },
  computed: {
    showList() {
      const result = [];
      for (let i = 0; i < 20; i += 1) {
        result.push(this.showStart + i);
      }
      return result;
    }
  },
  mounted() {
    const io = new IntersectionObserver((entries) => {
      if (entries[0].intersectionRatio > 0.001) {
        if (entries[0].target.dataset.site === 'end') {
          this.showStart += 10;
        } else {
          this.showStart = (this.showStart - 10 <= 1) ? 1 : (this.showStart - 10);
        }
      }
    }, {
      threshold: [0.000001],
    });
    io.observe(this.$refs.start);
    io.observe(this.$refs.end);
  }
};

样式层

// lang="scss" scoped
.infinity-sroll-container{
  .item {
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 200px;
    font-weight: bold;
  }
  .end {
    position: relative;
    top: -400px;
  }
}

猜你喜欢

转载自www.cnblogs.com/lihao97/p/12031250.html
今日推荐