滚动相关知识点总结

获取当前滚动高度

也就是页面顶部超出视口的高度。html

function getScrollTop() {
  return document.body.scrollTop || document.documentElement.scrollTop;
}

document.documentElement获取到的是html标签。IE支持,chrome目前也支持。
document.body获取到的是body标签。chrome/ff支持。chrome

页面滚动的总高度
function getScrollHeight() {
  return document.body.scrollHeight || document.documentElement.scrollHeight;
}
视口高度
function getClientHeight() {
  return Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
}

window.innerHeight在IE8-不支持。而且会受到initial-scale缩放的影响。所以须要取一个max值。缓存

如何判断滚动到了顶部

scrollTop的值为0时,则滚动到了顶部。闭包

if (getScrollTop() === 0) {
  // 滚动到了顶部
}
如何判断滚动到了最低部

当滚动高度scrollTop与视口高度clientHeight之和,大于等于总高度scrollHeight时,则表示滚动到了底部。app

var curHeight = getScrollTop() + getClientHeight();
if (curHeight >= getScrollHeight()) {
  // 滚动到了底部
}
如何判断滚动方向
var preTop = 0;
var curTop = 0;
var timer = null;

document.addEventListener('scroll', () => {
  clearTimeout(timer);
  curTop = getScrollTop();

  if (curTop > preTop) {
    console.log('向下滚动');
  } 

  if (curTop < preTop) {
    console.log('向上滚动');
  }

  timer = setTimeout(() => {
    preTop = curTop;
  }, 10);
  
}, !1);
函数节流

下降函数的触发频率。函数

原理是经过闭包与setTimeout,缓存一个timer值。 当timer值不为null时,阻止操做重复执行。每一次操做执行完毕,将timer设置为null。这样下一次操做将不会受到阻止。若是咱们须要调节执行频率,只须要改变setTimeout的延迟时间便可。this

const throttle = (fn, delay) => {
  let timer = null;
  let isFrist = true;  // 第一次直接执行

  return function() {
    const args = [].slice.call(arguments);
    const self = this;

    if (timer) {
      return false;
    }

    if (isFrist) {
      fn.apply(self, args);
      isFrist = false;
    }

    timer = setTimeout(() => {
      clearTimeout(timer);
      timer = null;
      fn.apply(self, args);
    }, delay || 500)
  }
}

demo代码spa

var preTop = 0;
var curTop = 0;
var timer = null;

document.addEventListener('scroll', throttle(() => {
  clearTimeout(timer);
  curTop = getScrollTop();
  console.log(document.documentElement.scrollTop, document.documentElement.scrollHeight);

  if (getScrollTop() + getClientHeight() >= getScrollHeight()) {
    console.log('到底了兄弟.');
  }

  if (curTop > preTop) {
    console.log('向下滚动');
  } 

  if (curTop < preTop) {
    console.log('向上滚动');
  }

  timer = setTimeout(() => {
    preTop = curTop;
  }, 10);
}, 300), !1);


console.log('视口高度: ', window.innerHeight, document.documentElement.clientHeight);


function getScrollTop() {
  return document.body.scrollTop || document.documentElement.scrollTop;
}

function getScrollHeight() {
  return document.body.scrollHeight || document.documentElement.scrollHeight;
}

function getClientHeight() {
  return Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
}

function log() {
  console.log('xxx');
}

function throttle(fn, delay) {
  let timer = null;
  let isFrist = true;  // 第一次直接执行

  return function() {
    const args = [].slice.call(arguments);
    const self = this;

    if (timer) {
      return false;
    }

    if (isFrist) {
      fn.apply(self, args);
      isFrist = false;
    }

    timer = setTimeout(() => {
      clearTimeout(timer);
      timer = null;
      fn.apply(self, args);
    }, delay || 500)
  }
}
应用场景

滚动加载更多 | 滚动判断某些元素的显示与隐藏 | 视差滚动特效 等。code

一次需求中须要用到这些知识点,作了一个小小的总结以便记忆查询,欢迎你们补充,多多交流,一块儿进步。

clipboard.png

相关文章
相关标签/搜索