Javascript零碎之各類寬高屬性及應用

在Javascript的開發過程當中,咱們總會看到相似以下的邊界條件判斷(懶加載):git

const scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;    
const scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight;
const innerHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight 
   
if( scrollTop +innerHeight >= scrollHeight + 50) {
  console.log('滾動到底了!')
}

這些獲取滾動狀態的屬性,可能咱們咋一看可以理解,不過期間久了立馬又忘記了。這是由於這些獲取各類寬高的屬性api及其的多,並且幾乎都存在兼容性寫法。一方面很難記,更重要的是很差理解。下面經過選取經常使用的幾個來說述下具體api的區別。github

## 一 掛在window上的api

window上最經常使用的只有window.innerWidth/window.innerHeight、window.pageXOffset/window.pageYOffset.瀏覽器

其中,window.innerWidth/windw.innerHeight永遠都是窗口的大小,跟隨窗口變化而變化。window.pageXOffset/window.pageYOffset是IE9+瀏覽器獲取滾動距離的,實質跟document.documentElement/document.body上的scrollTop/scrollLeft功能一致,因此平常都使用兼容寫法:spa

const scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
pageYOffset 屬性實質是 window.scrollY 屬性的別名,pageXOffset同理,爲了跨瀏覽器兼容,通常用後者(pageYOffset、pageXOffset)。

二 掛在document上的

1 clientWidth/clientHeight:元素內部的寬高.

記住公式:3d

clientWidth/clientHeight = padding + content寬高 - scrollbar寬高(若有滾動條)

2 offsetWidth/offsetHeight

我的以爲這個名字有點誤導人,壓根沒有偏移的意思,記住公式便可:code

offsetWidth/offsetHeight = clientWidth/clientHeight(padding + content) + border + scrollbar

由上述公式,能夠獲得第一個示例,即"獲取滾動條的寬度(scrollbar)":blog

const el = document.querySelect('.box')
const style = getComputedStyle(el, flase)//獲取樣式
const clientWidth = el.clientWidth, offsetWidth = el.offsetWidth
//parseFloat('10px', 10) => 10
const borderWidth = parseFloat(style.borderLeftWidth, 10) + parseFloat(style.borderRightWidth, 10)
const scrollbarW = offsetWidth - clientWidth - borderWidth

3 offsetTop/offsetLeft

這兩個纔是真的意如其名,指的是元素上側或者左側偏移它的offsetParent的距離。這個offsetParent是距該元素最近的position不爲static的祖先元素,若是沒有則指向body元素。說白了就是:"元素div往外找到最近的position不爲static的元素,而後該div的邊界到它的距離"。
由此,能夠獲得第二個示例,即"得到任一元素在頁面中的位置":事件

const getPosition = (el) => {
    let left = 0, top = 0;

    while(el.offsetParent) {
        //獲取偏移父元素的樣式,在計算偏移的時候須要加上它的border
        const pStyle = getComputedStyle(el.offsetParent, false);
        left += el.offsetLeft + parseFloat(pStyle.borderLeftWidth, 10);
        top += el.offsetTop + parseFloat(pStyle.borderTopWidth, 10);
        el = el.offsetParent;
    }

    return { left, top }
}

那麼,offsetLeft和style.left有什麼區別呢?ip

  • offsetLeft 只讀,能夠返回沒有定位盒子的距離左側的位置,值爲number,例100。
  • style.left 可讀可寫,可是讀取時前提是設置過left,值爲字符串,例:"100px"

因此,通常通用用法是:「用offsetLeft 和 offsetTop 獲取值,用style.left 和 style.top 賦值」

綜上,結合getBoundingClientRect()獲得綜合示例"元素是否在可視區域":

function isElemInViewport(el) {
    const rt = el.getBoundingClientRect();

    return (
        rt.top >=0 &&
        rt.left >= 0 &&
        rt.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
        rt.right <= (window.innerWidth || document.documentElement.clientWidth)
    )
}

其中,getBoundingClientRect用於得到頁面中某個元素的左,上,右和下分別相對瀏覽器視窗的位置:
clipboard

三 掛在event上的

event上面的相對距離通常是鼠標點擊或者移動端觸控事件獲取的。

1 clientX clientY

鼠標或者觸控點相對於可視窗口左上角爲原點x軸和y軸的距離:
image

2 offsetX offsetY

鼠標或者觸控點相對於元素自己寬高左上角爲原點x軸和y軸的距離:
image

3 screenX screenY

鼠標或者觸控點相對於屏幕顯示器左上角爲原點x軸和y軸的距離:
image

4 pageX pageY

鼠標或者觸控點相對於頁面內容左上角爲原點x軸和y軸的距離:
image
須要注意的是,這兩個屬性存在兼容性問題:

pageX = event.pageX || event.x; //IE
pageY = event.pageY || event.y; //IE
本文收錄在我的的Github上 https://github.com/kekobin/bl... ,以爲有幫助的,歡迎start哈。支持原創,未經本人贊成,請勿轉載!
相關文章
相關標籤/搜索