IntersectionObserver 實現上/下無限滾動


無限滾動

很多人以為無限滾動,就是只是觸底加載,但是加載到一定長度,頁面會爆炸!!

真正的無限加載是真正的無限!
頁面僅渲染可見的元素,對不可見的不占用頁面節點,才可實現真正的無限滾動。

無限滾動-1

無限滾動-1
![無限滾動-2](https://images.cnblogs.com/cnblogs_com/lihao97/1612453/o_19121211454620191212_191047_38.jpg)
無限滾動-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;
  }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM