新聞中心
當(dāng)今已有很多的JS框架封裝了獲取Dom元素的坐標(biāo)的方法,我們可以直接使用,而這里我更多的是希望透過這些方法,看到原始的獲取坐標(biāo)方式以及如何處理跨瀏覽器問題。

創(chuàng)新互聯(lián)專注于網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計、網(wǎng)頁設(shè)計、網(wǎng)站制作、網(wǎng)站開發(fā)。公司秉持“客戶至上,用心服務(wù)”的宗旨,從客戶的利益和觀點(diǎn)出發(fā),讓客戶在網(wǎng)絡(luò)營銷中找到自己的駐足之地。尊重和關(guān)懷每一位客戶,用嚴(yán)謹(jǐn)?shù)膽B(tài)度對待客戶,用專業(yè)的服務(wù)創(chuàng)造價值,成為客戶值得信賴的朋友,為客戶解除后顧之憂。
獲取Dom元素的X/Y坐標(biāo)
現(xiàn)在Web頁面的交互方式越來越多樣化,其中拖放頁面元素也是一種很常見的操作。在這類操作當(dāng)中有兩個主要問題需要解決,一個是事件的注冊方式,一般處理拖放元素的事件順序是:捕獲鼠標(biāo)正鍵按下——注冊鼠標(biāo)移動事件——捕獲鼠標(biāo)正鍵抬起——注銷鼠標(biāo)移動事件;另一個問題就是拖放元素的位置,即X/Y坐標(biāo)。這里我主要來講述后面的問題:如何獲取一個Dom元素的坐標(biāo)。
當(dāng)今已有很多的JS框架封裝了獲取Dom元素的坐標(biāo)的方法,我們可以直接使用,而這里我更多的是希望透過這些方法,看到原始的獲取坐標(biāo)方式以及如何處理跨瀏覽器問題。
首先認(rèn)識一下getBoundingClientRect方法,標(biāo)準(zhǔn)語法為:
- oRect=object.getBoundingClientRect();
Dom節(jié)點(diǎn)調(diào)用該方法可返回一個ClientRect類型的對象,該對象有四個屬性值:top、left、right、bottom,表示了該節(jié)點(diǎn)相對于可視瀏覽器可視區(qū)域的左上角位置的坐標(biāo),看圖就能好理解:
坐標(biāo)說明圖1
補(bǔ)充一下,如果當(dāng)前的元素已經(jīng)超出可視區(qū)域,依然按照可視區(qū)域的左上角位置的坐標(biāo)來計算,如圖2
坐標(biāo)說明圖2
這樣就可以簡單的獲取Dom元素在可視區(qū)里的X/Y坐標(biāo)(通過left和top屬性)。最后在計算上頁面滾動條的偏移量就可以計算出元素在整個頁面中的X/Y坐標(biāo)了。頁面滾動偏移量的計算在不同瀏覽器下有所不同,不過我們可以借鑒YUI里面方法,設(shè)計一個通用的方式:
- scrollLeft=Math.max(document.documentElement.scrollLeft,
- document.body.scrollLeft);
- scrollTop=Math.max(document.documentElement.scrollTop,
- document.body.scrollTop);
在W3C標(biāo)準(zhǔn)下document.body.scrollTop和document.body.scrollLeft都為0,所以采用了上面兼容的方式獲取頁面滾動條的偏移量。#p#
◆將ClientRect對象的left、top屬性分別加上scrollLeft和scrollTop,就能獲取Dom元素的X/Y坐標(biāo)了。但對于IE8之前的IE版本在很多情況,下面要對這個值進(jìn)行一些調(diào)整,有三種情況,下面來分別看一下:
1.IE6的標(biāo)準(zhǔn)模式下不需要調(diào)整;
2.所有怪異模式下為取document的當(dāng)前borderLeftWidth和borderTopWidth值做調(diào)整,分別加在X/Y坐標(biāo)值上;
3.其他的情況都分別在X/Y坐標(biāo)值上加上2;
這樣就可以獲取最后準(zhǔn)確的X/Y坐標(biāo)了。
如果所有的瀏覽器都能如此就好了,可惜有些瀏覽器(FF2、Safari)不支持getBoundingClientRect方法。需要通過一級級查找和計算offsetParent來獲取X/Y坐標(biāo)值。這里首先介紹什么是元素的offsetParent屬性。
◆offsetParent屬性是距離調(diào)用offsetParent的元素最近的(在包含層次中最靠近的),并且是已進(jìn)行過CSS定位的與容器元素。首先說明一下CSS定位,是指對元素設(shè)置position屬性為absolute、relative或fixed(IE6除外),還有一個問題是元素在table元素中時會有不同的情況。下面是我的一些歸納,不全之處望大家指出:
1.元素不在table元素中,且元素及其所有上級元素都未進(jìn)行CSS定位時,這個元素的offsetParent屬性為根元素(Body);
2.元素本身沒進(jìn)行CSS定位,而出現(xiàn)在table中或有上級元素進(jìn)行了CSS定位,那么當(dāng)向上先達(dá)到TD元素時該元素的offsetParent屬性為TD元素;當(dāng)向上先達(dá)到進(jìn)行了CSS定位的上級元素時該元素的offsetParent屬性為該上級元素;
3.無論元素在不在table中,只要元素本身進(jìn)行了CSS定位,有上級元素進(jìn)行了CSS定位的則元素的offsetParent屬性為該上級元素,沒有上級素進(jìn)行了CSS定位的則元素的offsetParent屬性為根元素;
知道了offsetParent屬性的含義,就可以通過offsetParent屬性來一級級的計算X/Y坐標(biāo)了。一種比較簡單的while循環(huán):
- varnode;/*求坐標(biāo)的元素*/
- varxy=[];/*保存XY坐標(biāo)*/
- while((nodenode=node.offsetParent)){
- xy[0]+=node.offsetLeft;
- xy[1]+=node.offsetTop];
- }
◆通過這一個循環(huán)就能累計元素每級offsetParent屬性元素的偏移量,但這個偏移量在累加的過程中沒有計算每級父元素有滾動條的情況,最后還要同getBoundingClientRect方法一樣加上頁面滾動值(這里scrollLeft和scrollTop)。現(xiàn)在先來累計計算元素每上級元素的滾動條情況,首先判斷元素本身是不是設(shè)置了position為fixed:
1.設(shè)置了則不用計算每上級元素的滾動條情況,但需要對Opera和其他瀏覽器做區(qū)分,Opera瀏覽器減去scrollLeft和scrollTopxy[0]-=scrollLeft;xy[1]-=scrollTop;,其他情況是加上scrollLeft和scrollTop。
- xy[0]+=scrollLeft;xy[1]+=scrollTop;
2.未設(shè)置時就需要累計計算元素每上級元素的滾動條,通過一個循環(huán)里累加:
- while((nodenode=node.parentNode)&&node.tagName){
- scrollTop=node.scrollTop;
- scrollLeft=node.scrllLeft;
- if(scrollTop||scrollLeft){
- xy[0]-=scrollLeft;
- xy[1]-=scrollTop;
- }
- }
最后機(jī)上頁面滾動值
- xy[0]+=scrollLeft;xy[1]+=scrollTop;
這樣最后就可以在不支持getBoundingClientRect方法的瀏覽器下獲取元素的X/Y坐標(biāo)了。
總結(jié):
如果瀏覽器支持getBoundingClientRect方法,通過該方法再加上頁面滾動條的偏移就能獲取元素的X/Y了(不同瀏覽器需要微調(diào)),如果不支持getBoundingClientRect方法,則需要通過循環(huán)該元素的每級offsetParent屬性來累計偏移量,再通過每個父級元素的滾動條來調(diào)整,最后再加上頁面滾動條的偏移來獲取元素的X/Y坐標(biāo)。獲取X/Y坐標(biāo)的方式還有很多,可能不盡相同,我這里主要是基于YUI里面的思想和方法。
網(wǎng)站名稱:技術(shù)分享如何獲取Dom元素的X/Y坐標(biāo)
當(dāng)前地址:http://www.dlmjj.cn/article/cddosce.html


咨詢
建站咨詢
