關(guān)于js各種dom高度及相對(duì)位置 & 鼠標(biāo)位置

參考文獻(xiàn)
segmentfault獲取屏幕寬高
js中位置與大小的獲取方法
深入理解客戶區(qū)尺寸client
css clientheight、offsetheight、scrollheight詳解

關(guān)于鼠標(biāo)位置參考文獻(xiàn)
clientX,offsetX,layerX,pageX,screenX,X鼠標(biāo)位置全解

需要提前了解的知識(shí)點(diǎn)

  • 在 DOM 術(shù)語中,client 總是指除邊框(border)外的渲染盒子(內(nèi)邊距+內(nèi)容大小)。offset 總是指包含邊框的渲染盒子(邊框+內(nèi)邊距+內(nèi)容大?。ヽlientTop 即為這兩者的 Top 之差,即邊框?qū)挾?/li>
  • 除了html元素外滾動(dòng)條是從border開始的

documentElement && body

documentElement 對(duì)應(yīng)的html標(biāo)簽
body對(duì)應(yīng)的是什么不用說了吧

clientHeight && clientWidth (可視區(qū)高度)

客戶區(qū)大小指的是元素內(nèi)容及其內(nèi)邊距所占據(jù)的空間大小

clientHeight = padding-top + height + padding-bottom
clientWidth = padding-left + width + padding-right

在chrome實(shí)際測(cè)試中:bodyclientHeight包括了marginborder
clientWidth包括marginborder
documentElementclientHeightclientWidth包含了maringborder
在chrome中的測(cè)試結(jié)果發(fā)現(xiàn):瀏覽器的滾動(dòng)條,并不是在html元素的內(nèi)部,而是在html元素margin的外部,這也是為什么document.documentElement.scrollTop/scrollLeftdocument.documentElement.clientWidth/clientHeight不受htmlmarginborder的影響

document.body.clientHeight
17:49:29.017 1496
17:49:34.408 document.body.clientWidth
17:49:34.412 1354
17:49:45.289 document.body.style.border = "50px solid black";
17:49:45.294 "50px solid black"
17:49:54.891 document.body.clientWidth
17:49:54.893 1254
17:50:00.495 document.body.clientHeight
17:50:00.497 1496
17:50:14.902 document.documentElement.clientHeight
17:50:14.905 451
17:50:23.377 document.documentElement.clientWidth
17:50:23.378 1354
17:50:47.907 document.documentElement.style.border = "50px solid blue";
17:50:47.911 "50px solid blue"
17:50:56.567 document.documentElement.clientWidth
17:50:56.570 1354
17:51:04.695 document.documentElement.clientHeight
17:51:04.699 451

clientWidth/clientHeight屬性返回元素節(jié)點(diǎn)的客戶區(qū)寬度,滾動(dòng)條寬度不計(jì)算在內(nèi)

1.jpg

offsetWidth && offsetHeight

offsetWidth=(border-width)*2+(padding-left)+(width)+(padding-right)
offsetHeight=(border-width)*2+(padding-top)+(height)+(padding-bottom)

每次訪問客戶區(qū)client屬性都需要重新計(jì)算,重復(fù)訪問需要耗費(fèi)大量的性能,所以要盡量避免重復(fù)訪問這些屬性。如果需要重復(fù)訪問,則把它們的值保存在變量中,以提高性能

包括滾動(dòng)條寬度或者高度
如果給元素設(shè)置了display:none,則客戶區(qū)client屬性都為0

offsetLeft && offsetTop

經(jīng)過chrome的檢測(cè):
offsetTop表示元素的上外邊框至offsetParent元素的上內(nèi)邊框之間的像素距離
offsetLeft表示元素的左外邊框至offsetParent元素的左內(nèi)邊框之間的像素距離

對(duì)于css position:absolute中的定位:left和right是值得整個(gè)盒模型到父盒子內(nèi)邊框的距離

offsetParent

參考文獻(xiàn):
深入理解定位父級(jí)offsetParent及偏移大小

定位父級(jí)offsetParent的定義是:與當(dāng)前元素最近的經(jīng)過定位(position不等于static)的父級(jí)元素,主要分為下列幾種情況

  • 元素自身有fixed定位,offsetParent的結(jié)果為null
    • 當(dāng)元素自身有fixed固定定位時(shí),我們知道固定定位的元素相對(duì)于視口進(jìn)行定位,此時(shí)沒有定位父級(jí),offsetParent的結(jié)果為null
    • [注意]firefox瀏覽器有兼容性問題,firefox會(huì)返回body其他瀏覽器返回null
  • 元素自身無fixed定位,且父級(jí)元素都未經(jīng)過定位,offsetParent的結(jié)果為<body>
  • 元素自身無fixed定位,且父級(jí)元素存在經(jīng)過定位的元素,offsetParent的結(jié)果為離自身元素最近的經(jīng)過定位的父級(jí)元素
  • <body>元素的parentNode是null

看幾個(gè)關(guān)于offsetParent的應(yīng)用場景

    //獲得距離`offsetParent`的距離

var top_rel_to_parent = ele.offsetTop;

var left_rel_to_parent = ele.offsetLeft;

//獲得相對(duì)于頁面的距離

function getNodePosition(node) {

        var _node = node;

    var top = left = 0;

    while (node) {

        if (node.tagName) {

            top = top + node.offsetTop + node.clientTop;

            left = left + node.offsetLeft + node.clientLeft;

            node = node.offsetParent;

        }

        else {

            node = node.parentNode;

        }

    }
    return [top - _node.clientTop, left - _node.clientLeft];

}

//獲得頁面滾動(dòng)的距離

function getScroll() {

    if(typeof pageYOffset !=  'undefined') {

        return [pageYOffset, pageXOffset];

    }

    else {

        var B = document.body;

        var D = document.documentElement;

        D = (D.clientHeight) ? D : B;

        return [D.scrollTop, D.scrollLeft];

    }

}

  // 最后可以獲得相對(duì)視口距離

var top_rel_to_viewport = top_rel_to_doc - getScroll()[0];

var left_rel_to_viewport = left_rel_to_doc - getScroll()[1];

window.screen.width && height

屏幕的寬高分辨率

window.screen.availWidth && availHeight

屏幕的可用分辨率(還不清楚對(duì)于不同系統(tǒng)指的是什么)

window.innerWidth && window.innerHeight

window.innerWidthwindow.innerHeight:獲得的是可視區(qū)域的寬高,但是window.innerWidth寬度包含了縱向滾動(dòng)條的寬度,window.innerHeight高度包含了橫向滾動(dòng)條的高度(IE8以及低版本瀏覽器不支持)。

window.outerWidth && window.outerHeight

window.outerWidthwindow.outerHeight:獲得的是加上工具條與滾動(dòng)條窗口的寬度與高度。

clientLeft && clientTop

返回邊框?qū)挾?/p>

在chrome中這兩個(gè)量對(duì)于body,documentElement來說都是能正常取到的:

document.body.style.border = "50px solid black";
document.documentElement.style.border = "50px solid blue";
document.body.clientTop
17:52:17.529 50
17:52:27.093 document.body.clientLeft
17:52:27.094 50
17:52:35.874 document.documentElement.clientTop
17:52:35.880 50

如果display為inline時(shí),clientLeft屬性和clientTop屬性都返回0

scrollTop && scrollLeft

當(dāng)前元素的視口距離頂部的高度,和左邊的距離
也可以說是滾動(dòng)條,滾動(dòng)的距離

pageYOffset && pageXOffset

相當(dāng)于 document.documentElement.scrollTopdocument.documentElement.scrollLeft

ele.getBoundingClientRect()

用于獲取元素外邊框相對(duì)于瀏覽器文檔的位置參數(shù)(x, y)_值得注意的是,這一點(diǎn)對(duì)于chrome沒有實(shí)現(xiàn),對(duì)于ff已經(jīng)實(shí)現(xiàn)了
offsetWidth,offsetHeight(width, height)
元素外邊框相對(duì)于瀏覽器視口位置(top, left)

(x, y)的值應(yīng)該是(left,top)加上window.pageXOffset, window.pageYOffset

scrollX && scrollY

為了跨瀏覽器兼容,請(qǐng)使用 window.pageXOffsetwindow.pageYOffset 代替 window.scrollXwindow.scrollY。不能訪問這些屬性的腳本可以使用下面的代碼:

// For scrollX
(((t = document.documentElement) || (t = document.body.parentNode))
  && typeof t.scrollLeft == 'number' ? t : document.body).scrollLeft
// For scrollY
(((t = document.documentElement) || (t = document.body.parentNode))
  && typeof t.scrollTop == 'number' ? t : document.body).scrollTop

待整理

網(wǎng)頁可見區(qū)域?qū)挘篸ocument.body.clientWidth
網(wǎng)頁可見區(qū)域高:document.body.clientHeight
網(wǎng)頁可見區(qū)域?qū)挘篸ocument.body.offsetWidth (包括邊線的寬)
網(wǎng)頁可見區(qū)域高:document.body.offsetHeight (包括邊線的寬)
網(wǎng)頁正文全文寬:document.body.scrollWidth
網(wǎng)頁正文全文高:document.body.scrollHeight
網(wǎng)頁被卷去的高:document.body.scrollTop
網(wǎng)頁被卷去的左:document.body.scrollLeft
網(wǎng)頁正文部分上:window.screenTop
網(wǎng)頁正文部分左:window.screenLeft
屏幕分辨率的高:window.screen.height
屏幕分辨率的寬:window.screen.width
屏幕可用工作區(qū)高度:window.screen.availHeight
屏幕可用工作區(qū)寬度:window.screen.availWidth

HTML精確定位:scrollLeft,scrollWidth,clientWidth,offsetWidth
scrollHeight: 獲取對(duì)象的滾動(dòng)高度。
scrollLeft:設(shè)置或獲取位于對(duì)象左邊界和窗口中目前可見內(nèi)容的最左端之間的距離
scrollTop:設(shè)置或獲取位于對(duì)象最頂端和窗口中可見內(nèi)容的最頂端之間的距離
scrollWidth:獲取對(duì)象的滾動(dòng)寬度
offsetHeight:獲取對(duì)象相對(duì)于版面或由父坐標(biāo) offsetParent 屬性指定的父坐標(biāo)的高度
offsetLeft:獲取對(duì)象相對(duì)于版面或由 offsetParent 屬性指定的父坐標(biāo)的計(jì)算左側(cè)位置
offsetTop:獲取對(duì)象相對(duì)于版面或由 offsetTop 屬性指定的父坐標(biāo)的計(jì)算頂端位置
event.clientX 相對(duì)文檔的水平座標(biāo)
event.clientY 相對(duì)文檔的垂直座標(biāo)
event.offsetX 相對(duì)容器的水平坐標(biāo)
event.offsetY 相對(duì)容器的垂直坐標(biāo)
document.documentElement.scrollTop 垂直方向滾動(dòng)的值
event.clientX+document.documentElement.scrollTop 相對(duì)文檔的水平座標(biāo)+垂直方向滾動(dòng)的量

IE,F(xiàn)ireFox 差異如下:

IE6.0、FF1.06+:
clientWidth = width + padding
clientHeight = height + padding
offsetWidth = width + padding + border
offsetHeight = height + padding + border

IE5.0/5.5:
clientWidth = width - border
clientHeight = height - border
offsetWidth = width
offsetHeight = height

(需要提一下:CSS中的margin屬性,與clientWidth、offsetWidth、clientHeight、offsetHeight均無關(guān))
網(wǎng)頁可見區(qū)域?qū)挘?document.body.clientWidth
網(wǎng)頁可見區(qū)域高: document.body.clientHeight
網(wǎng)頁可見區(qū)域?qū)挘?document.body.offsetWidth (包括邊線的寬)
網(wǎng)頁可見區(qū)域高: document.body.offsetHeight (包括邊線的高)
網(wǎng)頁正文全文寬: document.body.scrollWidth
網(wǎng)頁正文全文高: document.body.scrollHeight
網(wǎng)頁被卷去的高: document.body.scrollTop
網(wǎng)頁被卷去的左: document.body.scrollLeft
網(wǎng)頁正文部分上: window.screenTop
網(wǎng)頁正文部分左: window.screenLeft
屏幕分辨率的高: window.screen.height
屏幕分辨率的寬: window.screen.width
屏幕可用工作區(qū)高度: window.screen.availHeight
屏幕可用工作區(qū)寬度: window.screen.availWidth
-------------------
技術(shù)要點(diǎn)
本節(jié)代碼主要使用了Document對(duì)象關(guān)于窗口的一些屬性,這些屬性的主要功能和用法如下。
要得到窗口的尺寸,對(duì)于不同的瀏覽器,需要使用不同的屬性和方法:若要檢測(cè)窗口的真實(shí)尺寸,在Netscape下需要使用Window的屬性;在IE下需要 深入Document內(nèi)部對(duì)body進(jìn)行檢測(cè);在DOM環(huán)境下,若要得到窗口的尺寸,需要注意根元素的尺寸,而不是元素。
Window對(duì)象的innerWidth屬性包含當(dāng)前窗口的內(nèi)部寬度。Window對(duì)象的innerHeight屬性包含當(dāng)前窗口的內(nèi)部高度。
Document對(duì)象的body屬性對(duì)應(yīng)HTML文檔的標(biāo)簽。Document對(duì)象的documentElement屬性則表示HTML文檔的根節(jié)點(diǎn)。
document.body.clientHeight表示HTML文檔所在窗口的當(dāng)前高度。document.body. clientWidth表示HTML文檔所在窗口的當(dāng)前寬度。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容