IntersectionObserverスクロールロード

14228 ワード

IntersectionObserver
定義#テイギ#
つまり、指定したクロススケールでルート要素とターゲット要素がコールバックをトリガーするのを監視します.
互換性
  • 互換部分現代遊覧器(chrome)生産環境で使用し、互換需要
  • に注意してください.
    シーンの操作
  • onscroll 1の代わりに一定の使用シーンがあり、書き方がより簡単で優雅である2、onscrollによる大量の位置計算を回避し、性能を向上させる
  • .
  • 例えば1:スクロール(プルアップ)ロード
  • 例えば2:怠惰負荷
  • APIの紹介
    インスタンスの作成
    var observer = new IntersectionObserver(callback,options);
    

    パラメータ
    callback:スケール交差時にトリガーされるコールバックを指定
     new IntersectionObserver((entries) => { 
     },options)
    
  • entriesは交差状態を記述し、具体的にはentries
  • が見られる.
    options:構成パラメータ
    フィールド
    を選択します.
    デフォルト
    説明
    root
    element
    null(デフォルトはブラウザウィンドウ)
    ルート要素
    rootMargin   
    string
    0
    root外距離は、marginのように負の数('10 px-10 px 10 px-10 px')であってもよい.
    threshold
    number/ary   
    0
    コールバックをトリガーするクロススケール
    方法
  • IntersectionObserverEntry.boundingClientRect IntersectionObserverオブジェクトのリスニングを停止する
  • IntersectionObserver.observe()オブジェクトのobserve()メソッド方向ですが、複数のターゲット要素を監視して、これらのターゲット要素の表示領域の変化を表示できます.
  • IntersectionObserver.takeRecords()は、すべての観察対象のIntersectionObserverEntryオブジェクト配列
  • を返します.
  • IntersectionObserver.unobserve()は、IntersectionObserverに特定のターゲット要素のリスニングを停止させます.

  • より多くのインプリメンテーションをロード(オリジナル)
    index.html
  • 哨兵
  • として固定要素を設置する
    
      
    ...LoadingMore....

    index.js
    class LoadMore {
      constructor(options) {
        this.observer = null
        this.rootNode = document.getElementById(options.root) //     
        this.obsNode = document.getElementById(options.obs) //     
        this.loadMoreFn = options.loadMoreFn //     
        this.pageNum = 0 //     
        this.total = -1 //     -1 //     
        this.init() //    
      }
      //       
      callback = entries => {
        console.log(entries)
        //                 
        if (entries[0].intersectionRatio === 0) return
        this.pageNum += 1
        this.loadMoreFn(this.pageNum)
      }
      //       
      canclobserve() {
        console.log('  ')
        this.observer.unobserve(this.obsNode)
      }
      //           
      hanldeObserve() {
        this.observer.observe(this.obsNode)
      }
      //    
      init() {
        //    IntersectionObserver    
        this.observer = new IntersectionObserver(this.callback, {
          root: this.rootNode || null, //     、   
          rootMargin: '0px', //             
          threshold: [0.8] //     (0~1),          
        })
        this.hanldeObserve()
      }
    }
  • コールバックが要素挿入を呼び出すと、歩哨要素の基礎rootが再びトリガーされ、交差コールバックif(entries[0].intersectionRatio==0)returnがこれによって防止される
  • よびだし
    let loadEx = new LoadMore({
      root: 'content',
      obs: 'bottom',
      loadMoreFn: pageNum => {
        //          
        if (pageNum * 10 > list.length) {
          loadEx.canclobserve()
        }
        setTimeout(() => {
          //   dom
          let curPage = list.slice((pageNum - 1) * 10, pageNum * 10)
          //       
          let frm = document.createDocumentFragment()
          for (let i = 0; i < curPage.length; i++) {
            let li = document.createElement('li')
            li.innerHTML = curPage[i]
            li.className = 'item-list'
            frm.appendChild(li)
          }
          document.getElementById('list').appendChild(frm)
          frm = null
        }, Math.random() * 3000)
      }
    })
    

    vueカスタム命令実装
    Vue.directive('loadMore', {
      bind: function(el, binding) {
        let opation = binding.value
        let div = document.createElement('div')
        div.id = 'footGuard'
        div.style.width = '100%'
        div.style.height = '20px'
        el.appendChild(div)
        el.observer = new IntersectionObserver(
          entries => {
            if (entries[0].intersectionRatio === 0) return
            opation()
          },
          {
            root: el || null, //     、   
            rootMargin: '100px', //             
            threshold: 0.5 //     (0~1),          
          }
        )
        el.observer.observe(div)
      },
      inserted: function() {},
      update: function() {},
      componentUpdated: function() {},
      unbind: function() {}
    })
    

    コンポーネント内での使用
    
    
    
    
    
    let createList = function (index) {
      let ary = []
      for (let i = index; i < index + 10; i++) {
        ary.push({
          id: i,
          name: 'index' + i
        })
      }
      return ary
    }
    
    export default {
      data () {
        return {
          list: []
        };
      },
      //    
      methods: {
        queryList: function () {
          setTimeout(() => {
            this.list = this.list.concat(createList(this.list.length - 1))
          }, (Math.random() + 1) * 1000)
        }
      },
      //      -     (    DOM  )
      mounted () {
        this.queryList()
      }
    }