自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

技術(shù)分享 如何獲取Dom元素的X/Y坐標(biāo)

開發(fā) 前端
本文和大家一起學(xué)習(xí)一下如何獲取Dom元素的X/Y坐標(biāo),當(dāng)今已有很多的JS框架封裝了獲取Dom元素的坐標(biāo)的方法,我們可以直接使用。

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

獲取Dom元素的X/Y坐標(biāo)

現(xiàn)在Web頁面的交互方式越來越多樣化,其中拖放頁面元素也是一種很常見的操作。在這類操作當(dāng)中有兩個(gè)主要問題需要解決,一個(gè)是事件的注冊(cè)方式,一般處理拖放元素的事件順序是:捕獲鼠標(biāo)正鍵按下——注冊(cè)鼠標(biāo)移動(dòng)事件——捕獲鼠標(biāo)正鍵抬起——注銷鼠標(biāo)移動(dòng)事件;另一個(gè)問題就是拖放元素的位置,即X/Y坐標(biāo)。這里我主要來講述后面的問題:如何獲取一個(gè)Dom元素的坐標(biāo)。

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

首先認(rèn)識(shí)一下getBoundingClientRect方法,標(biāo)準(zhǔn)語法為:

  1. oRect=object.getBoundingClientRect();  
  2.  

Dom節(jié)點(diǎn)調(diào)用該方法可返回一個(gè)ClientRect類型的對(duì)象,該對(duì)象有四個(gè)屬性值:top、left、right、bottom,表示了該節(jié)點(diǎn)相對(duì)于可視瀏覽器可視區(qū)域的左上角位置的坐標(biāo),看圖就能好理解:

坐標(biāo)說明圖1

DOM元素坐標(biāo)說明圖1

補(bǔ)充一下,如果當(dāng)前的元素已經(jīng)超出可視區(qū)域,依然按照可視區(qū)域的左上角位置的坐標(biāo)來計(jì)算,如圖2

坐標(biāo)說明圖2

DOM元素坐標(biāo)說明圖2

這樣就可以簡單的獲取Dom元素在可視區(qū)里的X/Y坐標(biāo)(通過left和top屬性)。最后在計(jì)算上頁面滾動(dòng)條的偏移量就可以計(jì)算出元素在整個(gè)頁面中的X/Y坐標(biāo)了。頁面滾動(dòng)偏移量的計(jì)算在不同瀏覽器下有所不同,不過我們可以借鑒YUI里面方法,設(shè)計(jì)一個(gè)通用的方式:

  1. scrollLeft=Math.max(document.documentElement.scrollLeft,  
  2.  
  3. document.body.scrollLeft);  
  4.  
  5. scrollTop=Math.max(document.documentElement.scrollTop,  
  6.  
  7. document.body.scrollTop);  

在W3C標(biāo)準(zhǔn)下document.body.scrollTop和document.body.scrollLeft都為0,所以采用了上面兼容的方式獲取頁面滾動(dòng)條的偏移量。#p#

◆將ClientRect對(duì)象的left、top屬性分別加上scrollLeft和scrollTop,就能獲取Dom元素的X/Y坐標(biāo)了。但對(duì)于IE8之前的IE版本在很多情況,下面要對(duì)這個(gè)值進(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方法。需要通過一級(jí)級(jí)查找和計(jì)算offsetParent來獲取X/Y坐標(biāo)值。這里首先介紹什么是元素的offsetParent屬性。

◆offsetParent屬性是距離調(diào)用offsetParent的元素最近的(在包含層次中最靠近的),并且是已進(jìn)行過CSS定位的與容器元素。首先說明一下CSS定位,是指對(duì)元素設(shè)置position屬性為absolute、relative或fixed(IE6除外),還有一個(gè)問題是元素在table元素中時(shí)會(huì)有不同的情況。下面是我的一些歸納,不全之處望大家指出:

1.元素不在table元素中,且元素及其所有上級(jí)元素都未進(jìn)行CSS定位時(shí),這個(gè)元素的offsetParent屬性為根元素(Body);

2.元素本身沒進(jìn)行CSS定位,而出現(xiàn)在table中或有上級(jí)元素進(jìn)行了CSS定位,那么當(dāng)向上先達(dá)到TD元素時(shí)該元素的offsetParent屬性為TD元素;當(dāng)向上先達(dá)到進(jìn)行了CSS定位的上級(jí)元素時(shí)該元素的offsetParent屬性為該上級(jí)元素;

3.無論元素在不在table中,只要元素本身進(jìn)行了CSS定位,有上級(jí)元素進(jìn)行了CSS定位的則元素的offsetParent屬性為該上級(jí)元素,沒有上級(jí)素進(jìn)行了CSS定位的則元素的offsetParent屬性為根元素;

知道了offsetParent屬性的含義,就可以通過offsetParent屬性來一級(jí)級(jí)的計(jì)算X/Y坐標(biāo)了。一種比較簡單的while循環(huán):

  1. varnode;/*求坐標(biāo)的元素*/  
  2. varxy=[];/*保存XY坐標(biāo)*/  
  3. while((nodenode=node.offsetParent)){  
  4. xy[0]+=node.offsetLeft;  
  5. xy[1]+=node.offsetTop];  

◆通過這一個(gè)循環(huán)就能累計(jì)元素每級(jí)offsetParent屬性元素的偏移量,但這個(gè)偏移量在累加的過程中沒有計(jì)算每級(jí)父元素有滾動(dòng)條的情況,最后還要同getBoundingClientRect方法一樣加上頁面滾動(dòng)值(這里scrollLeft和scrollTop)。現(xiàn)在先來累計(jì)計(jì)算元素每上級(jí)元素的滾動(dòng)條情況,首先判斷元素本身是不是設(shè)置了position為fixed:

1.設(shè)置了則不用計(jì)算每上級(jí)元素的滾動(dòng)條情況,但需要對(duì)Opera和其他瀏覽器做區(qū)分,Opera瀏覽器減去scrollLeft和scrollTopxy[0]-=scrollLeft;xy[1]-=scrollTop;,其他情況是加上scrollLeft和scrollTop。

  1. xy[0]+=scrollLeft;xy[1]+=scrollTop;  
  2.  

2.未設(shè)置時(shí)就需要累計(jì)計(jì)算元素每上級(jí)元素的滾動(dòng)條,通過一個(gè)循環(huán)里累加:

  1. while((nodenode=node.parentNode)&&node.tagName){  
  2. scrollTop=node.scrollTop;  
  3. scrollLeft=node.scrllLeft;  
  4. if(scrollTop||scrollLeft){  
  5. xy[0]-=scrollLeft;  
  6. xy[1]-=scrollTop;  
  7. }  

最后機(jī)上頁面滾動(dòng)值

  1. xy[0]+=scrollLeft;xy[1]+=scrollTop;  
  2.  

這樣最后就可以在不支持getBoundingClientRect方法的瀏覽器下獲取元素的X/Y坐標(biāo)了。

總結(jié):

如果瀏覽器支持getBoundingClientRect方法,通過該方法再加上頁面滾動(dòng)條的偏移就能獲取元素的X/Y了(不同瀏覽器需要微調(diào)),如果不支持getBoundingClientRect方法,則需要通過循環(huán)該元素的每級(jí)offsetParent屬性來累計(jì)偏移量,再通過每個(gè)父級(jí)元素的滾動(dòng)條來調(diào)整,最后再加上頁面滾動(dòng)條的偏移來獲取元素的X/Y坐標(biāo)。獲取X/Y坐標(biāo)的方式還有很多,可能不盡相同,我這里主要是基于YUI里面的思想和方法。
 

【編輯推薦】

  1. JQuery創(chuàng)建DOM元素方法解析
  2. W3C DOM模型用法詳解
  3. JavaScript獲取HTML DOM節(jié)點(diǎn)元素詳解
  4. 深入了解JavaScript HTML DOM對(duì)象
  5. 解析HTML DOM Checkbox對(duì)象的屬性和方法

 

 

責(zé)任編輯:佚名 來源: ued.koubei.com
相關(guān)推薦

2010-09-13 16:46:29

JavaScriptHTML DOM節(jié)點(diǎn)

2021-04-09 18:01:03

前端ReactDOM

2010-10-09 10:56:50

DHTMLJS

2010-10-09 13:56:33

textareaJavascript

2024-01-15 09:23:16

框架方式原生

2023-10-30 08:35:50

水波紋效果vue

2010-09-28 13:40:52

DOM元素

2010-09-25 16:06:58

SQL語句

2010-08-11 14:47:54

Flex樣式

2010-07-28 12:41:18

Flex組件

2010-06-02 16:09:05

SVN協(xié)議

2010-07-15 15:21:07

Perl線程

2010-09-10 13:06:27

JavaScript

2013-04-12 12:36:13

WindowsPhon

2010-09-28 15:27:09

JavaScript

2021-01-11 07:51:16

DOM對(duì)象節(jié)點(diǎn)樹

2013-01-09 15:27:45

DOM XSS檢測QtWebKitXSS

2017-09-27 14:46:37

Vue2.xDOM diff原理

2021-01-18 07:15:22

虛擬DOM真實(shí)DOMJavaScript

2013-08-06 15:16:27

技術(shù)人創(chuàng)業(yè)開發(fā)者創(chuàng)業(yè)移動(dòng)互聯(lián)網(wǎng)創(chuàng)業(yè)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)