你想知道的HTML位置信息都在這裏了

前言

在一次的波紋效果的實現中,由於用到了不少的HTML的位置信息,以前記得也就一兩個,此次去翻閱MDN後發現,關於HTML的位置信息居然後不少參數。因而以爲有必要將這些位置信息參數的含義作個總結,方便之後參考。html

一、Element

Element在是最通用的基類,一個DOM結構中全部的對象都是繼承於它。包括後面介紹的HTMLElement也是繼承於它。因此待會Element的屬性HtmlElement也會擁有。chrome

1.一、clientHeight/clientWidth/clientLeft/clientTop

這四個參數標識的是元素的內部高度/寬度/左邊border的寬度/上面border的寬度。其標識的含義以下圖所示:數組

clientHeight是元素內部的高度,包含內邊距也就是padding-top/padding-bottom,可是不包含水平滾動條、邊框、和margin。瀏覽器

同理clientWidth也是如此。bash

clientLeft表示一個元素的左邊框的寬度,有一些兼容性的問題能夠詳細參考Element.clientLeftide

clientTop也是如此。佈局

四個參數的具體取值咱們如下面的demo來說解。測試

咱們使用超多的內容去填充div標籤,而且設置了overflow屬性讓其出現水平滾動條或者垂直滾動條,可是這四個參數不爲所動,驗證了上面咱們剛纔說的事實。ui

1.二、scrollHeight/scrollLeft/scrollLeftMax/scrollTop/scrollTopMax/scrollWidth

這6個參數和滾動相關,在頁面的設計中不免會出現滾動條,想要知道用戶滾到到哪一個位置就須要用到上面的某些參數來輔助你的判斷。spa

scrollHeight標識元素的內容高度,注意和剛纔的clientHeight加以區別。當元素不足以展現所有內容的時候使用overflow屬性致使出現不可視的內容區域(也就是出現滾動條)的時候,這些不可視的內容也是包括在內的。在沒有垂直滾動條的狀況下,scrollHeight值與元素視圖填充全部內容所須要的最小值clientHeight相同,它包含了元素的padding,但不包含margin。

scrollWidth也是相似。

scrollLeft能夠讀取或設置元素滾動條到元素左邊的距離。

Tips

注意若是這個元素的內容排列方向(direction) 是rtl (right-to-left) ,那麼滾動條會位於最右側(內容開始處),而且scrollLeft值爲0。此時,當你從右到左拖動滾動條時,scrollLeft會從0變爲負數(這個特性在chrome瀏覽器中不存在)

scrollLeftMax返回一個Number表示一個元素橫向滾動條可滾動的最大距離,兼容性比較差,屬於新特性,謹慎使用。

scrollTop相似於scrollLeft。

scrollTopMax相似於scrollLeftMax。

咱們使用下面demo來講明上面幾個參數的用法。

在demo中咱們輸出上面的四個參數(scrollLeftMax/scrollTopMax當前Chrome(v61)不支持)。 結果是:

scrollHeight: 222 scrollLeft: 0 scrollTop: 0 scrollWidth: 336

複製代碼

當咱們把內容減小讓其不要出現滾動條的時候:

能夠看到:

scrollHeight: 102 scrollLeft: 0 scrollTop: 0 scrollWidth: 102 clientHeight: 102 clientWidth: 102 clientLeft: 2 clientTop: 2
複製代碼

clientHeight === scrollHeight/clientWidth === scrollWidth

1.三、getBoundingClientRect()/getClientRects()

這兩個方法也是用來獲取元素的位置以及大小相關的信息。getClientRects返回的是個數組,數組中有不少個相似getBoundingClientRect返回的對象。getBoundingClientRect返回的永遠是最外框框的那個矩形區域相關的座標偏移對象;而getClientRects是多行文字區域的座標偏移集合,在非IE瀏覽器下,只對inline的標籤有反應。

通常getBoundingClientRect方法用的多一點。咱們能夠很容易獲取某個元素的偏移值。甚至高寬都能很輕鬆的計算出來。

1.3.一、getBoundingClientRect()

getBoundingClientRect返回一個DOMRect對象

DOMRect對象包含了一組用於描述邊框的只讀屬性——left、top、right和bottom,單位爲像素。除了 width 和 height 外的屬性都是相對於視口的左上角位置而言的。

對象裏面的元素以下表(引自DOMRect)

屬性 類型 描述
bottom float Y 軸,相對於視口原點(viewport origin)矩形盒子的底部。只讀。
height float 矩形盒子的高度(等同於 bottom 減 top)。只讀。
left float X 軸,相對於視口原點(viewport origin)矩形盒子的左側。只讀。
right float X 軸,相對於視口原點(viewport origin)矩形盒子的右側。只讀。
top float Y 軸,相對於視口原點(viewport origin)矩形盒子的頂部。只讀。
width float 矩形盒子的寬度(等同於 right 減 left)。只讀。
x float X軸橫座標,矩形盒子左邊相對於視口原點(viewport origin)的距離。只讀。
y float Y軸縱座標,矩形盒子頂部相對於視口原點(viewport origin)的距離。只讀。

在這個demo中咱們看到對應的值:

(bottom,height,left,right,top,width,x,y): 114,106,9,115,8,106,9,8}

如何獲得這些值呢?我繪製了這麼一張圖片,各個參數的取值由來羅列出來了:

須要注意的有如下幾點:

  1. body元素瀏覽器默認給了8px
  2. body元素的margin和test1元素的margin-top發生了margin collapsing(外邊距塌陷),因此獲得的top值爲8px,y值爲8px
  3. right的值左邊會包含元素的margin-left,可是不會包含margin-right,因此其值等於115,同理bottom也是。

1.3.二、getClientRects()

getClientRects返回一個ClientRect對象集合。提供以下的demo來解釋這個方法:

能夠在demo中能夠看到第一個結果由於文字換行的個數獲得集合數組的長度。每一行文字的位置信息咱們經過打印均可以看到,按照如今顯示是兩行,結果以下:

{"0":{"x":9,"y":5,"width":512.21875,"height":28,"top":5,"right":521.21875,"bottom":33,"left":9},"1":{"x":8,"y":27,"width":424.3125,"height":28,"top":27,"right":432.3125,"bottom":55,"left":8}}
複製代碼

而div元素的不支持,因此始終獲得的結果是一個,這個結果和獲取getBoundingClientRect是同樣的:

{"0":{"x":9,"y":75,"width":526,"height":50,"top":75,"right":535,"bottom":125,"left":9}}
複製代碼

因此該方法主要用於判斷行內元素是否換行,以及行內元素的每一行的位置偏移

二、HTMLElement

HTMLElement中介紹的是HTMLElement能夠標識任何HTML元素。除了繼承Element以外,它一樣有一系列屬於本身的位置參數定義。

2.一、offsetHeight/offsetLeft/offsetParent/offsetTop/offsetWidth

對塊級元素來講,offsetTopoffsetLeftoffsetWidthoffsetHeight描述了元素相對於offsetParent的邊界框。

然而,對於可被截斷到下一行的行內元素(如span),offsetTopoffsetLeft描述的是第一個邊界框的位置(使用Element.getClientRects()來獲取其寬度和高度),而offsetWidthoffsetHeight描述的是邊界框的尺寸(使用 Element.getBoundingClientRect 來獲取其位置)。

  1. HTMLElement.offsetParent是一個只讀屬性,返回一個指向最近的(closest,指包含層級上的最近)包含該元素的定位元素。若是沒有定位的元素,則 offsetParent 爲最近的table, table cell根元素(標準模式下爲html;quirks模式下爲body)。當元素的 style.display 設置爲 "none" 時,offsetParent返回null。offsetParent 頗有用,由於offsetTopoffsetLeft都是相對於其內邊距邊界的。

  2. offsetHeight獲取元素的像素高度,包括元素的邊框、內邊距和元素的水平滾動條(若是存在且渲染的話),不包含:before或:after等僞類元素的高度,且是一個整數。這個屬性值會被四捨五入爲整數值,若是你須要一個浮點數值,請用element.getBoundingClientRect()

  3. offsetLeft返回當前元素左上角相對於HTMLElement.offsetParent節點的左邊界偏移的像素值。

  4. offsetWidth是一個只讀屬性,返回一個元素的佈局寬度。一個典型的(譯者注:各瀏覽器的offsetWidth可能有所不一樣)offsetWidth是測量包含元素的邊框(border)、水平線上的內邊距(padding)、豎直方向滾動條(scrollbar)(若是存在的話)、以及CSS設置的寬度(width)的值。

  5. offsetTop爲只讀屬性,它返回當前元素相對於其 offsetParent 元素的頂部的距離

其測試的demo以下:

三、事件中關於位置的信息

當咱們使用click事件或者touch事件的時候也一樣會涉及到位置信息。Event包含了不少事件的定義,目前咱們只關注MouseEventTouchEvent

3.一、MouseEvent

鼠標點擊事件,該事件接口可由這些事件觸發:click/dbclick/mouseup/mousedown

MouseEvent繼承自UIEvent,UIEvent繼承自Event

該事件接口咱們關注三個參數:button/clientX/clientY/offsetX/offsetY/pageX/pageY/screenX/screenY。它們分別對應的信息是:

  1. button標識哪一種按鈕被按了,通常有如下5種類型: 0: 標識主按鈕觸發的,通常指的是左邊按鈕或者是未初始化的狀態 1: 輔助按鈕觸發的,通常指的是滾輪按鈕或者是中間的按個按鈕(若是存在的話) 2: 次級按鈕觸發的,通常指的是右邊按鈕 3: 第四個按鈕,通常指的是瀏覽器的返回按鈕 4: 第五個按鈕,通常指的是瀏覽器的前進按鈕

  2. clientX 是隻讀屬性, 它提供事件發生時的應用客戶端區域的水平座標 (與頁面座標不一樣)。例如,不論頁面是否有水平滾動,當你點擊客戶端區域的左上角時,鼠標事件的 clientX 值都將爲 0 。最初這個屬性被定義爲長整型(long integer),現在CSSOM視圖模塊將其從新定義爲雙精度浮點數(double float),clientY相似。

  3. movementX 是隻讀屬性,它提供了當前事件和上一個mousemove事件之間鼠標在水平方向上的移動值。換句話說,這個值是這樣計算的 : currentEvent.movementX = currentEvent.screenX - previousEvent.screenX.movementY相似。

  4. offsetX是鼠標點擊的位置相對於目標節點內邊位置的X座標,offsetY相似。

  5. pageX 是一個由MouseEvent接口返回的相對於整個文檔的x(水平)的座標。這個屬性考慮任何頁面的水平方向上的滾動。 起初這個屬性被定義爲長整型。 CSSOM 視圖模塊將它從新定位爲雙浮點數類型。

  6. screenX是隻讀屬性,標識鼠標點擊的位置在全局座標中橫軸的偏移位置。screenY相似。

  7. x屬性是clientX的簡寫,值等於clientX.

3.二、TouchEvent

觸摸事件,經常使用於移動端設備。一次觸摸能夠產生一個Touch對象,TouchEvent中的touches表明了全部當前接觸觸摸平面的觸點的 Touch對象。此次咱們着重關注touches這個屬性。

touches是一個集合,集合裏面的對象包含的屬性大體和MouseEvent的是同樣。可是也有些特有的屬性:

  1. identifier: 此 Touch 對象的惟一標識符. 一次觸摸動做(咱們值的是手指的觸摸)在平面上移動的整個過程當中, 該標識符不變. 能夠根據它來判斷跟蹤的是不是同一次觸摸過程.

  2. radiusX標識可以包圍用戶和觸摸平面的接觸面的最小橢圓的水平軸(X軸)半徑. 這個值的單位和 screenX 相同.radiusY相似

  3. rotationAngle: 它是這樣一個角度值:由radiusX 和 radiusY 描述的正方向的橢圓,須要經過順時針旋轉這個角度值,才能最精確地覆蓋住用戶和觸摸平面的接觸面.

  4. force:手指擠壓觸摸平面的壓力大小, 從0.0(沒有壓力)到1.0(最大壓力)的浮點數.取決於移動設備的支持。

  5. target是觸摸最開始觸摸到的元素。哪怕在觸點移動過程當中, 觸點的位置已經離開了這個元素的有效交互區域, 或者這個元素已經被從文檔中移除. 須要注意的是, 若是這個元素在觸摸過程當中被移除, 這個事件仍然會指向它, 可是不會再冒泡這個事件到 window 或 document 對象. 所以, 若是有元素在觸摸過程當中可能被移除, 最佳實踐是將觸摸事件的監聽器綁定到這個元素自己, 防止元素被移除後, 沒法再從它的上一級元素上偵測到從該元素冒泡的事件

兩者事件的demo以下:

要查看touchEvent的位置信息須要把該demo在Chrome上調爲移動端模式,點擊一下框便可獲得點擊的位置信息。

四、最後的總結

屬性 類型 說明
clientHeight/clientWidth float 元素內部的高度,只包含內邊距也就是padding-top/padding-bottom,width相似
clientLeft/clientTop float 元素的左邊框/上邊框的寬度
scrollHeight/scrollWidth float 標識元素的內容高度內容寬度
scrollLeft/scrollTop float 能夠讀取或設置元素滾動條到元素左邊/上邊的距離
getBoundingClientRect().bottom/top float Y 軸,相對於視口原點(viewport origin)矩形盒子的底部/頂部。
getBoundingClientRect().height/width float 矩形盒子的高度/寬度(等同於 bottom 減 top/right 減 left)。
getBoundingClientRect().left/right float X 軸,相對於視口原點(viewport origin)矩形盒子的左/右側。
getBoundingClientRect().x/y float X/Y軸橫座標,矩形盒子左邊/頂部相對於視口原點(viewport origin)的距離。只讀。
offsetHeight/offsetWidth int 元素的像素高度,包括元素的邊框、內邊距和元素的水平滾動條(若是存在且渲染的話),不包含:before或:after等僞類元素的高度
offsetLeft/offsetTop int 當前元素相對於其 offsetParent 元素的頂部的距離/左上角相對於HTMLElement.offsetParent節點的左邊界偏移的像素值
clientX/clientY long 鼠標點擊事件發生時的應用客戶端區域的水平座標 (與頁面座標不一樣)
movementX/movementY float 當前事件和上一個mousemove事件之間鼠標在水平/垂直方向上的移動值
offsetX/offsetY float 鼠標點擊的位置相對於目標節點內邊位置的X/Y座標
pageX/pageY float 一個由MouseEvent接口返回的相對於整個文檔的x/y(水平/垂直)的座標
screenX/screenY long 標識鼠標點擊的位置在全局(屏幕)座標中橫軸/縱軸的偏移位置
radiusX/radiusY float 可以包圍用戶和觸摸平面的接觸面的最小橢圓的水平/縱軸軸(X/Y軸)半徑

Tips:

  1. 帶有client字眼的屬性通常是衡量屬性自身的尺寸(不包含不可見區域)
  2. 帶有offset字眼的屬性通常指的是元素相對於某個參照物的位置信息
  3. 帶有page字眼的屬性通常指的是元素相對於整個視圖包括滾動未見的區域的位置信息
  4. 帶有screen字眼的屬性通常指的是元素相對於視圖不包括不可見區域的位置信息

參考

  1. TouchEvent.touches
  2. Touch
相關文章
相關標籤/搜索