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


對頁面中元素的坐標信息的獲取一直很困惑,今天在網上發現了一篇寫的還不錯的文章,翻譯出來與大家共享,有什么問題也歡迎提出來:

原文參考:(http://javascript.info/tutorial/coordinates

元素坐標:

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

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

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

1. 坐標系統

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

 

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

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

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

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

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

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

 1 function getOffsetSum(elem) {
 3   var top=0, left=0
 5   while(elem) {
 7     top = top + parseInt(elem.offsetTop)
 9     left = left + parseInt(elem.offsetLeft)
11     elem = elem.offsetParent 
13  }
15   return {top: top, left: left}
17 }

但這種方式有兩個缺陷:

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

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

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

3. 正確的方式:elem.getBoundingClientRect

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

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

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

1 <input id="brTest" type="button" value="Show button.getBoundingClientRect()" onclick='showRect(this)'/>
2 
3 <script>
4 function showRect(elem) { 5   var r = elem.getBoundingClientRect() 6   alert("Top/Left: "+r.top+" / "+r.left) 7   alert("Right/Bottom: "+r.right+" / "+r.bottom) 8 } 9 </script>

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

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

 1 function getOffsetRect(elem) {  2     var box = elem.getBoundingClientRect()  3     var body = document.body  4     var docElem = document.documentElement  5     var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop  6     var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft  7     var clientTop = docElem.clientTop || body.clientTop || 0
 8     var clientLeft = docElem.clientLeft || body.clientLeft || 0
 9     var top  = box.top +  scrollTop - clientTop 10     var left = box.left + scrollLeft - clientLeft 11     return { top: Math.round(top), left: Math.round(left) } 12 }

計算步驟如下:

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

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

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

1 function getOffset(elem) { 2     if (elem.getBoundingClientRect) { 3         return getOffsetRect(elem) 4     } else { // old browser
5         return getOffsetSum(elem) 6  } 7 }

 

 


免責聲明!

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



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