怎样完成无穷转动

简介

无穷转动对我们来讲已经是很罕见的功用了,具体表现为当页面转动到某个位置时就自动加载数据,本文将讨论无穷转动的完成道理以及优化。

道理

我们先看看最简朴的无穷转动的例子:

function fetchData() {
  fetch(path).then(res => doSomeThing(res.data));
}

window.addEventListener('scroll', fetchData);

上面就是无穷转动最简朴的例子啦~
实在就是监听 window 对象的 scroll 事宜,然后再触发猎取数据的函数~

但是,上面的例子中另有许多题目,个中最大的题目就是 猎取数据的函数(今后叫 fetch 函数)没有触发前提, 我们还须要不停优化,才在临盆环境下运用。

增加触发前提

我们先想一想,平常情况下,fetch 函数的触发前提有哪些呢 ?

  • 在 fetch 过程当中不能反复触发

  • 没有更多数据的时刻不能再触发

  • 屏幕间隔容器边沿 xxx 的时刻触发

前两点很好处置惩罚,只需加个 isLoadingisEnd 的变量就能够了。
增加这两个变量以后,我们的代码就变成下面的模样啦:

var isLoading = false;
var isEnd = false;

function fetchData() {

  if ( !isLoading && !isEnd ) {

    isLoading = true;

    fetch(path).then(res => {
      isLoading = false;
      res.data.length === 0 && isEnd = true;
      doSomething(res.data);
    });

  }

}
window.addEventListener('scroll', fetchData);

第三点对不熟悉 DOM 的童鞋来讲就有点难度了~

盘算屏幕与容器边沿的间隔

我们以盘算屏幕底部与容器底部边沿为例:

如果有 api 能够直接获得元素底部与屏幕底部的间隔就最好啦,能够省去贫苦,但实际上并没有如许的 api。
但是,我们能够经由过程浏览器供应的两个 api,盘算出元素底部与屏幕底部之间的间隔。

第一个 api 是 window.innerHeight,它返回的是屏幕(viewport)高度。
第二个 api 就是 Element.getBoundingClientRect ,这个要领用来盘算元素边沿与屏幕(viewport)之间的间隔。
须要提示一下,Element.getBoundingClientRect 会获得这么一个类 Object 对象:

ClientRect {
  width: 760,   // 元素宽度
  height: 2500, // 元素高度
  top: -1352,   // 元素上边沿与屏幕上边沿的间隔
  bottom: 1239, // 元素下边沿与屏幕上边沿的间隔
  left: 760,    // 元素左边沿与屏幕左边沿的间隔
  right: 860    // 元素右边沿与屏幕左边沿的间隔
}

能够看看下面这图:

     +------> +--------------------------------------------------------+
     |        |                     document.body                      |
     |        |                                                        |
     |        |                                                        |
body.getBoundingClientRect().top                                       |
     |        |                                                        |
     |        |                                                        |
     |        +--------------------------------------------------------+
     |        | browser                                              x |
     +------> +--------------------------------------------------------+ <--+
     |        | window                                                 |    |
     |        |                                                        |    |
     |        |                                                        |    |
     |        |                                                        |    |
     |        |                                                        |    |
     |        |                                                        |    |
     |        |                                                        |    |
window.innerHeight                                                     |    |
     |        |                                                        |    |
     |        |                                                        |    |
     |        |                               body.getBoundingClientRect().bottom
     |        |                                                        |    |
     |        |                                                        |    |
     |        |                                                        |    |
     |        |                                                        |    |
     |        |                                                        |    |
     +------> +--------------------------------------------------------+    |
              |                                                        |    |
              |                                                        |    |
              |                                                        |    |
              |                                                        |    |
              |                                                        |    |
              |                                                        |    |
              +--------------------------------------------------------+ <--+



有了这两个 api,我们很轻易就能够盘算出元素底部边沿与屏幕底部边沿的位置啦~

我们再修正下我们的代码:

var isLoading = false;
var isEnd = false;
var triggerDistance = 200;

function fetchData() {

  var distance = container.getBoundingClientRect().bottom - window.innerHeight;
  if ( !isLoading && !isEnd && distance < triggerDistance ) {

    isLoading = true;

    fetch(path).then(res => {
      isLoading = false;
      res.data.length === 0 && isEnd = true;
      doSomething(res.data);
    });

  }

}
window.addEventListener('scroll', fetchData);

修正以后,当容器底部与屏幕底部间隔小于 200 的时刻,才会触发 fetch 函数,如许我们的无穷转动就越发有用啦!

支撑 window 之外的元素

但是,并非只要 window 才能够转动,具有高度的级块元素只需设置了 overflow: scroll 都是能够转动的。
我们须要再修正一下代码来让级块元素也支撑无穷转动!

function fetchData() { /* do something */ }
window.addEventListener('scroll', fetchData);
document.getElementById('container').addEventListener('scroll', fetchData);

很简朴吧!只须要为该容器元素增加一个 scroll 的事宜监听器就好啦!

出处

http://scarletsky.github.io/2016/04/20/how-to-implement-infinite-scroll/

参考资料

https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect

    原文作者:scarlex
    原文地址: https://segmentfault.com/a/1190000004974824
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞