沐鳴註冊平台官網_JS 判斷元素是否可以滾動

今天在解決 ios 移動端滾動穿透的問題時遇到一個問題,就是判斷元素能否滾動,把這個過程記錄下來。以下以縱向滾動為例,橫向滾動同理。

基礎概念

Element.scrollHeight

scrollHeight 是一個元素內容高度的度量,包括由於溢出導致的視圖中不可見的內容,scrollHeight 的值等於元素在不能出現滾動條的時候展示出視圖中所有內容所需要的最小高度。

如果元素內容能在不出現滾動條的情況下全部展示,那麼元素的 scrollHeight 和 clientHeight 相等。

Element.clientHeight

clientHeight 是指元素內部高度,包括 padding,但不包括 margin、border 以及 橫向滾動條。

clientHeight = css height + css padding – height of horizontal scrollbar (if present)

第一個方案

根據上面兩個定義,很容易就想到可以通過比較 scrollHeight 和 clientHeight 的大小來判斷元素是否可以滾動。最開始我就是這麼做的。

function eleCanScroll(ele) {
  return ele.scrollHeight > ele.clientHeight; 
}

使用之後發現這個方法大部分時候判斷是對的,但是在一些情況下就出現的偏差。
偏差1
查看demo
子元素超出父元素,而且父元素不設置 overflow: auto
偏差2
查看demo
子元素相對父元素絕對定位

上面的兩個 demo 中,雖然 box 元素的 scrollHeight 大於 clientHeight,但是並不能滾動。

其實原因從 scrollHeight 的定義中就能找到,scrollHeight 是一個元素內容高度的度量,包括由於溢出導致的視圖中不可見的內容,也就是說,只要元素的子元素沒有完全在父級內容框中显示出來,不管是因為定位還是 translate 偏移導致,父級元素的 scrollHeight 就一定大於 clientHeight。而這裏面很多情況下父級元素都是不能滾動的。

所以通過比較 scrollHeight 和 clientHeight 的大小來判斷元素是否可以滾動的方法是錯誤的,我看網上有的解決辦法是判斷父級元素的 overflow 屬性,但我們知道這樣也是不對的。

解決方案

正確的解決辦法就要從 scrollTop 上入手了。
Element.scrollTop

一個元素的 scrollTop 值是這個元素的頂部到視口可見內容(的頂部)的距離的度量。當一個元素的內容沒有產生垂直方向的滾動條,那麼它的 scrollTop 值為0。

scrollTop 可以被設置為任何整數值,同時注意:如果一個元素不能被滾動(例如,它沒有溢出,或者這個元素有一個”non-scrollable”屬性), scrollTop
將被設置為0

根據上面 scrollTop 的語法我們就能找到解決方案。我們可以設置元素的 scrollTop = 1,再獲取下 scrollTop,如果值變為 0,說明該元素不可以滾動。
代碼地址

function eleCanScroll(ele) {
  if (!ele instanceof htmlElement) {
    console.log("fuck off");
    return;
  }
  if (ele.scrollTop > 0) {
    return true;
  } else {
    ele.scrollTop++;
    // 元素不能滾動的話,scrollTop 設置不會生效,還會置為 0
    const top = ele.scrollTop;
    // 重置滾動位置
    top && (ele.scrollTop = 0);
    return top > 0;
  }
}

站長推薦

1.雲服務推薦: 國內主流雲服務商,各類雲產品的最新活動,優惠券領取。地址:阿里雲騰訊雲華為雲

2.廣告聯盟: 整理了目前主流的廣告聯盟平台,如果你有流量,可以作為參考選擇適合你的平台點擊進入

鏈接: http://www.fly63.com/article/detial/8127