2011-03-28 64 views
5

我試圖獲取頁面上元素的座標。我一直在使用的標準的方式來獲得它:使用內聯偏移量獲取元素左側/頂部的實際偏移量

var el = element, pos = {x: 0, y: 0}; 
while (el) { 
    pos.x += el.offsetLeft; 
    pos.y += el.offsetTop; 
    el = el.offsetParent; 
} 

但是,當有問題的元素具有display: block,並offsetParents之一具有display: inline;這種方法失敗。這是由於在this thread描述的事實:

The element starts in the middle of the text

後一些用jQuery試圖事實證明,他們的.offset() - 方法返回正確的偏移,我已經通過源看了,但不完全是如何發現他們這樣做。所以我的問題是:我如何得到確切的位置?我不能在這個項目中使用jQuery,並且the thread described earlier中的方法很麻煩,添加一個元素並且測試工作太多(性能角度),並且使用Element.getBoundingClientRect也不可用。

如果你喜歡嘗試出來,你可以去Apple.com在下面打開您的選擇和類型的調試器:

var el, el2; 
el = el2 = document.querySelector('#worldwide span'); 
var pos = {x: 0, y: 0}; 
while (el2) { 
    pos.x += el2.offsetLeft; 
    pos.y += el2.offsetTop; 
    el2 = el2.offsetParent; 
} 
alert("Calculated position: " + pos.x + "x" + pos.y + " window size: " + screen.width + "x" + screen.height); 

有了這個代碼,我得到:Calculated position: 1354x988 window size: 1280x800(即偏移左邊是方式屏幕,它顯然不是)

這怎麼可能?任何解決方案的想法?約稿?它不一定是確切的,但它必須比以前更好。謝謝。

編輯:這是爲了WebKit渲染引擎,澄清。

回答

2

我最終用WebKit的window.webkitConvertPointFromNodeToPage去了,但我一直在碰到一個錯誤,它會返回一個完全錯誤的位置。進一步調查發現,如果有問題的節點是display:inline,那麼它將返回層次結構中最後一個塊元素的位置。

搜索此圖像的分辨率沒有任何反應(我發現的所有內容都是關於webkitConvertPointFromNodeToPage實際上做了什麼以及WebKit的源代碼的非常基本的信息)。

通過猜測我發現它返回了正確的位置,如果元素有display: inline-block,所以如果元素是內聯的,那麼我將它改爲內聯塊,然後計算位置。

如果有人對此問題有更好的解決方案,我很樂意聽取您的意見!

編輯:

原來改變顯示風格,以inline-block的並不總是一個好主意,所以不是這樣做,我用這個方法:

var offset = {x: 0, y: 0}; 
if (getStyle(el, 'display') == 'inline') { 
    offset.x = el.offsetLeft - el.parentNode.offsetLeft; 
    offset.y = el.offsetTop - el.parentNode.offsetTop; 
} 

var point = window.webkitConvertPointFromNodeToPage(el, new WebKitPoint(0, 0)); 

return { 
    x: Math.round(point.x + offset.x), 
    y: Math.round(point.y + offset.y) 
} 

我取內聯孩子的偏移量Top/Left並從其父母中減去它。我真的不確定它是如何在有顯示功能的父母身上發揮作用的:內聯,但在90%的時間內工作。

但是,如果任何人有一個更好的主意,我仍然開放的建議。

1

很可能here你會發現在the source code of jQuery.offset中使用的想法的描述。

如果你看看here你可以看到offsetLeftoffsetTop在舊的IE版本中不太正確。

我明白理解這個或其他東西可以如何實現是很有趣的。你如何看待jQuery.offset函數的源代碼並不那麼容易。如果你希望你的代碼工作正確並且獨立於瀏覽器,那麼你最好只使用jQuery.offset而不是寫他自己的實現。

1

檢查webkitConvertPointFromNodeToPage源代碼揭示它使用元素渲染器對象進行計算,如果不存在這樣的渲染器,則它使用具有渲染器的neareset祖先。但是,當使用祖先渲染器時,它不會調整偏移量以考慮目標與祖先起源之間的原始差異。這意味着當相對於包含渲染器給出點時,該函數可以正確工作。如果你計算座標的元素沒有渲染器,你需要手動調整偏移到執行最近的祖先有它(使用offsetLeft /頂)。確切地知道哪些元素具有渲染器將需要更多的研究,但一般沒有內容,但會影響其它節點,如SPAN的顯示任何元素,不需要渲染。

1

我有同樣的問題,當使用$.offset().left使用jQuery,試圖得到一個字的段落內的位置。

$(document).ready()函數中使用$.offset().left產生了不正確的結果。

$(window).load()功能使用$.offset().left解決我的問題WebKit中。

在可能會影響佈局的浮動圖像元素或字體的情況下,這尤其相關。