用JavaScript獲取頁面元素的位置(引用自阮一峰博客)

制作網(wǎng)頁的過程中檩咱,你有時(shí)候需要知道某個(gè)元素在網(wǎng)頁上的確切位置。

下面的教程總結(jié)了Javascript在網(wǎng)頁定位方面的相關(guān)知識(shí)胯舷。

一刻蚯、網(wǎng)頁的大小和瀏覽器窗口的大小

首先,要明確兩個(gè)基本概念桑嘶。

一張網(wǎng)頁的全部面積炊汹,就是它的大小。通常情況下逃顶,網(wǎng)頁的大小由內(nèi)容和CSS樣式表決定讨便。

瀏覽器窗口的大小,則是指在瀏覽器窗口中看到的那部分網(wǎng)頁面積以政,又叫做viewport(視口)霸褒。

很顯然,如果網(wǎng)頁的內(nèi)容能夠在瀏覽器窗口中全部顯示(也就是不出現(xiàn)滾動(dòng)條)盈蛮,那么網(wǎng)頁的大小和瀏覽器窗口的大小是相等的废菱。如果不能全部顯示,則滾動(dòng)瀏覽器窗口抖誉,可以顯示出網(wǎng)頁的各個(gè)部分昙啄。

二、獲取網(wǎng)頁的大小

網(wǎng)頁上的每個(gè)元素寸五,都有clientHeight和clientWidth屬性梳凛。這兩個(gè)屬性指元素的內(nèi)容部分再加上padding的所占據(jù)的視覺面積,不包括border和滾動(dòng)條占用的空間梳杏。

(圖一 clientHeight和clientWidth屬性)

因此韧拒,document元素的clientHeight和clientWidth屬性,就代表了網(wǎng)頁的大小十性。

function getViewport(){

if (document.compatMode == "BackCompat"){

return {

width: document.body.clientWidth,

height: document.body.clientHeight

}

} else {

return {

width: document.documentElement.clientWidth,

height: document.documentElement.clientHeight

}

}

}

上面的getViewport函數(shù)就可以返回瀏覽器窗口的高和寬叛溢。使用的時(shí)候,有三個(gè)地方需要注意:

1)這個(gè)函數(shù)必須在頁面加載完成后才能運(yùn)行劲适,否則document對(duì)象還沒生成楷掉,瀏覽器會(huì)報(bào)錯(cuò)。

2)大多數(shù)情況下霞势,都是document.documentElement.clientWidth返回正確值烹植。但是斑鸦,在IE6的quirks模式中,document.body.clientWidth返回正確的值草雕,因此函數(shù)中加入了對(duì)文檔模式的判斷巷屿。

3)clientWidth和clientHeight都是只讀屬性,不能對(duì)它們賦值墩虹。

三嘱巾、獲取網(wǎng)頁大小的另一種方法

網(wǎng)頁上的每個(gè)元素還有scrollHeight和scrollWidth屬性,指包含滾動(dòng)條在內(nèi)的該元素的視覺面積诫钓。

那么旬昭,document對(duì)象的scrollHeight和scrollWidth屬性就是網(wǎng)頁的大小,意思就是滾動(dòng)條滾過的所有長(zhǎng)度和寬度菌湃。

仿照getViewport()函數(shù)问拘,可以寫出getPagearea()函數(shù)。

function getPagearea(){

if (document.compatMode == "BackCompat"){

return {

width: document.body.scrollWidth,

height: document.body.scrollHeight

}

} else {

return {

width: document.documentElement.scrollWidth,

height: document.documentElement.scrollHeight

}

}

}

但是慢味,這個(gè)函數(shù)有一個(gè)問題。如果網(wǎng)頁內(nèi)容能夠在瀏覽器窗口中全部顯示墅冷,不出現(xiàn)滾動(dòng)條纯路,那么網(wǎng)頁的clientWidth和scrollWidth應(yīng)該相等。但是實(shí)際上寞忿,不同瀏覽器有不同的處理驰唬,這兩個(gè)值未必相等。所以腔彰,我們需要取它們之中較大的那個(gè)值叫编,因此要對(duì)getPagearea()函數(shù)進(jìn)行改寫。

function getPagearea(){

if (document.compatMode == "BackCompat"){

return {

width: Math.max(document.body.scrollWidth,

document.body.clientWidth),

height: Math.max(document.body.scrollHeight,

document.body.clientHeight)

}

} else {

return {

width: Math.max(document.documentElement.scrollWidth,

document.documentElement.clientWidth),

height: Math.max(document.documentElement.scrollHeight,

document.documentElement.clientHeight)

}

}

}

四霹抛、獲取網(wǎng)頁元素的絕對(duì)位置

網(wǎng)頁元素的絕對(duì)位置搓逾,指該元素的左上角相對(duì)于整張網(wǎng)頁左上角的坐標(biāo)。這個(gè)絕對(duì)位置要通過計(jì)算才能得到杯拐。

首先霞篡,每個(gè)元素都有offsetTop和offsetLeft屬性,表示該元素的左上角與父容器(offsetParent對(duì)象)左上角的距離端逼。所以朗兵,只需要將這兩個(gè)值進(jìn)行累加,就可以得到該元素的絕對(duì)坐標(biāo)顶滩。

(圖二 offsetTop和offsetLeft屬性)

下面兩個(gè)函數(shù)可以用來獲取絕對(duì)位置的橫坐標(biāo)和縱坐標(biāo)余掖。

function getElementLeft(element){

var actualLeft = element.offsetLeft;

var current = element.offsetParent;

while (current !== null){

actualLeft += current.offsetLeft;

current = current.offsetParent;

}

return actualLeft;

}

function getElementTop(element){

var actualTop = element.offsetTop;

var current = element.offsetParent;

while (current !== null){

actualTop += current.offsetTop;

current = current.offsetParent;

}

return actualTop;

}

由于在表格和iframe中,offsetParent對(duì)象未必等于父容器礁鲁,所以上面的函數(shù)對(duì)于表格和iframe中的元素不適用盐欺。

五赁豆、獲取網(wǎng)頁元素的相對(duì)位置

網(wǎng)頁元素的相對(duì)位置,指該元素左上角相對(duì)于瀏覽器窗口左上角的坐標(biāo)找田。

有了絕對(duì)位置以后歌憨,獲得相對(duì)位置就很容易了,只要將絕對(duì)坐標(biāo)減去頁面的滾動(dòng)條滾動(dòng)的距離就可以了墩衙。滾動(dòng)條滾動(dòng)的垂直距離务嫡,是document對(duì)象的scrollTop屬性;滾動(dòng)條滾動(dòng)的水平距離是document對(duì)象的scrollLeft屬性漆改。

(圖三 scrollTop和scrollLeft屬性)

對(duì)上一節(jié)中的兩個(gè)函數(shù)進(jìn)行相應(yīng)的改寫:

function getElementViewLeft(element){

var actualLeft = element.offsetLeft;

var current = element.offsetParent;

while (current !== null){

actualLeft += current.offsetLeft;

current = current.offsetParent;

}

if (document.compatMode == "BackCompat"){

var elementScrollLeft=document.body.scrollLeft;

} else {

var elementScrollLeft=document.documentElement.scrollLeft;

}

return actualLeft-elementScrollLeft;

}

function getElementViewTop(element){

var actualTop = element.offsetTop;

var current = element.offsetParent;

while (current !== null){

actualTop += current. offsetTop;

current = current.offsetParent;

}

if (document.compatMode == "BackCompat"){

var elementScrollTop=document.body.scrollTop;

} else {

var elementScrollTop=document.documentElement.scrollTop;

}

return actualTop-elementScrollTop;

}

scrollTop和scrollLeft屬性是可以賦值的心铃,并且會(huì)立即自動(dòng)滾動(dòng)網(wǎng)頁到相應(yīng)位置,因此可以利用它們改變網(wǎng)頁元素的相對(duì)位置挫剑。另外去扣,element.scrollIntoView()方法也有類似作用,可以使網(wǎng)頁元素出現(xiàn)在瀏覽器窗口的左上角樊破。

六愉棱、獲取元素位置的快速方法

除了上面的函數(shù)以外,還有一種快速方法哲戚,可以立刻獲得網(wǎng)頁元素的位置奔滑。

那就是使用getBoundingClientRect()方法。它返回一個(gè)對(duì)象顺少,其中包含了left朋其、right、top脆炎、bottom四個(gè)屬性梅猿,分別對(duì)應(yīng)了該元素的左上角和右下角相對(duì)于瀏覽器窗口(viewport)左上角的距離。

所以秒裕,網(wǎng)頁元素的相對(duì)位置就是

var X= this.getBoundingClientRect().left;

var Y =this.getBoundingClientRect().top;

再加上滾動(dòng)距離袱蚓,就可以得到絕對(duì)位置

var X= this.getBoundingClientRect().left+document.documentElement.scrollLeft;

var Y =this.getBoundingClientRect().top+document.documentElement.scrollTop;

目前,IE几蜻、Firefox 3.0+癞松、Opera 9.5+都支持該方法,而Firefox 2.x入蛆、Safari响蓉、Chrome、Konqueror不支持哨毁。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末枫甲,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌想幻,老刑警劉巖粱栖,帶你破解...
    沈念sama閱讀 222,627評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異脏毯,居然都是意外死亡闹究,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門食店,熙熙樓的掌柜王于貴愁眉苦臉地迎上來渣淤,“玉大人,你說我怎么就攤上這事吉嫩〖廴希” “怎么了?”我有些...
    開封第一講書人閱讀 169,346評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵自娩,是天一觀的道長(zhǎng)用踩。 經(jīng)常有香客問我,道長(zhǎng)忙迁,這世上最難降的妖魔是什么脐彩? 我笑而不...
    開封第一講書人閱讀 60,097評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮姊扔,結(jié)果婚禮上惠奸,老公的妹妹穿的比我還像新娘。我一直安慰自己旱眯,他們只是感情好晨川,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,100評(píng)論 6 398
  • 文/花漫 我一把揭開白布证九。 她就那樣靜靜地躺著删豺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪愧怜。 梳的紋絲不亂的頭發(fā)上呀页,一...
    開封第一講書人閱讀 52,696評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音拥坛,去河邊找鬼蓬蝶。 笑死,一個(gè)胖子當(dāng)著我的面吹牛猜惋,可吹牛的內(nèi)容都是我干的丸氛。 我是一名探鬼主播,決...
    沈念sama閱讀 41,165評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼著摔,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼缓窜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,108評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤禾锤,失蹤者是張志新(化名)和其女友劉穎私股,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體恩掷,經(jīng)...
    沈念sama閱讀 46,646評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡倡鲸,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,709評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了黄娘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片峭状。...
    茶點(diǎn)故事閱讀 40,861評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖寸宏,靈堂內(nèi)的尸體忽然破棺而出宁炫,到底是詐尸還是另有隱情,我是刑警寧澤氮凝,帶...
    沈念sama閱讀 36,527評(píng)論 5 351
  • 正文 年R本政府宣布羔巢,位于F島的核電站,受9級(jí)特大地震影響罩阵,放射性物質(zhì)發(fā)生泄漏竿秆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,196評(píng)論 3 336
  • 文/蒙蒙 一稿壁、第九天 我趴在偏房一處隱蔽的房頂上張望幽钢。 院中可真熱鬧,春花似錦傅是、人聲如沸匪燕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽帽驯。三九已至,卻和暖如春书闸,著一層夾襖步出監(jiān)牢的瞬間尼变,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工浆劲, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嫌术,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,287評(píng)論 3 379
  • 正文 我出身青樓牌借,卻偏偏與公主長(zhǎng)得像度气,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子膨报,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,860評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 一磷籍、JS前言 (1)認(rèn)識(shí)JS 也許你已經(jīng)了解HTML標(biāo)記(也稱為結(jié)構(gòu))哲虾,知道了CSS樣式(也稱為表示),會(huì)使用HT...
    凜0_0閱讀 2,777評(píng)論 0 8
  • Window和document對(duì)象的區(qū)別 window對(duì)象window對(duì)象表示瀏覽器中打開的窗口window對(duì)象是...
    FConfidence閱讀 2,211評(píng)論 0 5
  • 早上6點(diǎn)45起床择示,陳誠(chéng)的電話打給我說我沒有按約定時(shí)間起床束凑,督促我要按約定時(shí)間起床。7點(diǎn)45送陳燃到學(xué)校栅盲。 ...
    31c47a10aded閱讀 180評(píng)論 0 0
  • 一個(gè)人汪诉,自己不能成為自己的障礙;兩個(gè)人谈秫,一方不應(yīng)是另一方的局限扒寄。一個(gè)人應(yīng)該具有明晰的方向,這需要常識(shí)做底拟烫,知識(shí)助力...
    李先生的雨閱讀 239評(píng)論 0 0
  • MarkDown是什么 是一個(gè)簡(jiǎn)單的標(biāo)記語言该编,這些標(biāo)記和 html 的一些標(biāo)簽對(duì)應(yīng)通過一些轉(zhuǎn)換庫可以把 markd...
    饑人谷_嚴(yán)琰閱讀 158評(píng)論 0 0