滾動相關知識點總結

獲取當前滾動高度

也就是頁面頂部超出視口的高度。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

相關文章
相關標籤/搜索