獲取元素相對瀏覽器窗口的偏移坐標


元素坐標:

  • 瀏覽器坐標系統
  • 使用offsetParent屬性獲取元素的坐標
  • 使用w3c標准屬性elem.getBoundingClientRect獲取元素的坐標
  • 結合以上兩種方式,實現兼容瀏覽器的獲取坐標方式
  • 摘要

*在瀏覽器中存在兩個坐標系統:*

  1. 相對文檔——坐標遠點在頁面的左上角
  2. 相對可視化窗口——坐標原點在可視窗口的左上角

1. 坐標系統

當頁面沒有滾動時,窗口和頁面共享相同的坐標原點,如下圖所示:

img

滾動后,頁面相對可視窗口發生了偏移如下圖:

img

事實上,在這兩種坐標系統間相互轉化很簡單,頁面坐標是窗口坐標加上頁面滾動偏移

大部分時候,僅僅使用頁面坐標,因為他們滾動后維持相同。

2. 使用offsetParent屬性獲取元素的坐標

元素的坐標是元素左上角的坐標,不幸的是沒有一個單一的屬性可以獲取到它的值,但可以是喲個offsetTop/offsetLeft和offsetParent計算它的值。

img

一種計算元素的絕對坐標的方式是遍歷offsetParent鏈,並對遍歷中的每個定位父元素的offsetLeft/offsetTop求和,如下所示:

function getOffsetSum(elem) {
  var top=0, left=0
  while(elem) {
    top = top + parseInt(elem.offsetTop)
    left = left + parseInt(elem.offsetLeft)
    elem = elem.offsetParent       
  }
  return {top: top, left: left}
}

但這種方式有兩個缺陷:

  1. 它存在bug,不同的瀏覽器存在不同的問題,當考慮邊框和滾動的時候會出現問題。

  2. 它計算起來很慢,每次都要遍歷整個offsetParents鏈

可以寫一個跨瀏覽器修復bug的方法,但先讓我們來看另外一種標准做法,該方法在IE6+,firefox3+ OPera ,和safrari及chrome中也支持

3. 正確的方式:elem.getBoundingClientRect

這個方式在W3C標准下有描述,大多數現代瀏覽器都支持,包括IE

它返回一個包裹元素的矩形框,這個矩形框以top , left , right , bottom四個屬性給出。

這四個數字代表了矩形的左上角和右下角的四個坐標,例如:

<input id="brTest" type="button" value="Show button.getBoundingClientRect()" onclick='showRect(this)'/>

<script>
function showRect(elem) {
  var r = elem.getBoundingClientRect()
  alert("Top/Left: "+r.top+" / "+r.left)
  alert("Right/Bottom: "+r.right+" / "+r.bottom)
}
</script>

這個坐標是相對窗口,而不是相對文檔。

讓我們來看一個新版本的計算坐標的方式:使用getBoundingClientRect

function getOffsetRect(elem) {
    var box = elem.getBoundingClientRect()
    var body = document.body
    var docElem = document.documentElement
    var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop
    var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft
    var clientTop = docElem.clientTop || body.clientTop || 0
    var clientLeft = docElem.clientLeft || body.clientLeft || 0
    var top  = box.top +  scrollTop - clientTop
    var left = box.left + scrollLeft - clientLeft
    return { top: Math.round(top), left: Math.round(left) }
}

計算步驟如下:

  1. 獲取到包含的矩形框
  2. 計算頁面的滾動,除了IE<9外,所有瀏覽器都支持pageXOffset / pageYOffset,在IE中,當設置了DOCTYPE時,滾動的值可以通過documentElement獲得,否則使用body對象獲取。
  3. 在IE中文檔會相對左上角偏移幾個像素,需要去掉它,減去clientTop和clientLeft
  4. 矩形框的坐標加上頁面相對窗口滾動的坐標,減去偏移的坐標,就得到了元素相對整個文檔的坐標。

4. 跨瀏覽器兼容的解決方案:

有很多js庫結合兩種方式,獲取元素的坐標:

function getOffset(elem) {
    if (elem.getBoundingClientRect) {
        return getOffsetRect(elem)
    } else { // old browser
        return getOffsetSum(elem)
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM