Vue獲取頁面元素的相對位置的方法示例
今天在開發(fā)源碼一處發(fā)現(xiàn)有一處需要獲取元素的相對位置高度,發(fā)現(xiàn)getBoundingClientRect有一個問題,它是用于獲取某個元素相對于視窗的位置集合,達(dá)不到我想要的要求,如是看到阮老師寫的一篇文章,關(guān)于用Javascript獲取頁面元素的位置,很好解決了我的我問題
發(fā)現(xiàn)問題
當(dāng)我滾動到元素的位置時候,我想把元素固定在頭部
// html 結(jié)構(gòu)
<div :class="['source-subnav', isFixed ? 'tab-nav-fixed' : '']" ref="subnav">
<ul>
<li class="active"><a href="javascript:;">首頁推薦</a></li>
<li><a href="javascript:;">最新發(fā)布</a></li>
</ul>
</div>
export default {
data(){
return {
isFixed:false,
}
},
mounted(){
if(this.$refs.subnav.getBoundingClientRect){
this.scrollTop(this.$refs.subnav.getBoundingClientRect())
}
},
methods:{
// 這是封裝的一個方法
scrollTop(h){
console.log(h);
this.utils.scrollTop((res)=>{
this.isFixed = res.scrollH > h ? true :false;
})
}
}
}
utils.js
// 該函數(shù)主要功能返回,滾動的高度以及文檔占比窗口高度的百分比
utils.scrollTop = function(callback){
// 頁面總高
var totalH = document.body.scrollHeight || document.documentElement.scrollHeight;
// 可視高
var clientH = window.innerHeight || document.documentElement.clientHeight;
var result = {}
window.addEventListener('scroll', function(e){
// 計(jì)算有效高
var validH = totalH - clientH
// 滾動條卷去高度
var scrollH = document.body.scrollTop || document.documentElement.scrollTop
// 百分比
result.percentage = (scrollH/validH*100).toFixed(2)
result.scrollH = scrollH;
callback && callback(result)
})
}

可以看到該元素的距離頂部595px,正常顯示
當(dāng)我先滾動一段距離后,然后再次刷新,滾動條位置還會記錄之前的位置,這是top為195px,這也是正常的,因?yàn)?code>getBoundingClientRect是根據(jù)瀏覽器窗口進(jìn)行定位置的
而我想要的是想要不管瀏覽器滾動條位置在何處時刷新瀏覽器,我所綁定的dom元素都是根據(jù)文檔左上角進(jìn)行定位的

offsetTop
網(wǎng)上有人說用offsetTop,其實(shí)offsetTop是對當(dāng)前對象到其上級層頂部的距離。不能對其進(jìn)行賦值.設(shè)置對象到頁面頂部的距離請用style.top屬性
獲取元素距離文檔頂部距離
返回值是一個 DOMRect 對象,這個對象是由該元素的 getClientRects() 方法返回的一組矩形的集合, 即:是與該元素相關(guān)的 CSS 邊框集合。 DOMRect 對象包含了一組用于描述邊框的只讀屬性: left、top、right 和 bottom,單位為像素。除了 width 和 height 外的屬性都是相對于視口的左上角位置而言的。 getBoundingClientRect返回值 top: 元素上邊框距離視窗頂部的距離 bottom: 元素下邊框距離視窗頂部的距離 left: 元素左邊框距離視窗左側(cè)的距離 right: 元素右邊框距離視窗左側(cè)的距離
由于getBoundingClientRect它們會隨著視窗的滾動而相應(yīng)的改變,那么元素距離頁面頂部的距離就是,再加上滾動距離
this.$refs.subnav.getBoundingClientRect().top + window.scrollY; 或者 this.$refs.subnav.getBoundingClientRect().top+document.documentElement.scrollTop;
window.scrollY不兼容ie9,如需兼容請看Window.scrollY
修改上方代碼
if(this.$refs.subnav.getBoundingClientRect){
var top1 = this.$refs.subnav.getBoundingClientRect().top + window.scrollY
var top2 = this.$refs.subnav.getBoundingClientRect().top+document.documentElement.scrollTop;
console.log(top1)
console.log(top2)
this.scrollTop(top)
}
效果如下,不管滾動條何處位置都是一個相對文檔最上面的左上角

阮一峰
function getElementTop(element){
var actualTop = element.offsetTop;
var current = element.offsetParent;
while (current !== null){
actualTop += current.offsetTop;
current = current.offsetParent;
}
return actualTop;
}
實(shí)現(xiàn)原理
offsetTop可以返回元素距離offsetParent屬性返回元素頂部的距離(如果父元素有定位的,那么將返回距離最近的定位元素,否則返回body元素,元素可能有多個定位元素,需要通過遞歸的方式層層獲取距離,然后相加
特別說明: 需要將body的外邊距設(shè)置為0,這樣元素距離body頂部的距離就等同于距離文檔頂部的距離
修改上方代碼
if(this.$refs.subnav.getBoundingClientRect){
var top1 = this.$refs.subnav.getBoundingClientRect().top + window.scrollY
var top2 = this.$refs.subnav.getBoundingClientRect().top+document.documentElement.scrollTop;
// getElementTop在上方
var top3 = getElementTop(this.$refs.subnav)
console.log(top1)
console.log(top2)
console.log(top3)
this.scrollTop(top)
}
效果如下

總結(jié)三種方法獲取元素距離文檔頂部位置
dom.getBoundingClientRect().top + window.scrollY;
或者
dom.getBoundingClientRect().top+document.documentElement.scrollTop;
或者
function getElementTop(element){
var actualTop = element.offsetTop;
var current = element.offsetParent;
while (current !== null){
actualTop += current.offsetTop;
current = current.offsetParent;
}
return actualTop;
}
參考文章
用Javascript獲取頁面元素的位置
獲取元素距離頁面頂部的距離
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Vue源碼學(xué)習(xí)之響應(yīng)式是如何實(shí)現(xiàn)的
最近接觸了vue.js,一度非常好奇vue.js是如何監(jiān)測數(shù)據(jù)更新并且重新渲染頁面,這篇文章主要給大家介紹了關(guān)于Vue源碼學(xué)習(xí)之響應(yīng)式是如何實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下2021-10-10
Vue動態(tài)添加屬性到data的實(shí)現(xiàn)
在vue中請求接口中,一個請求方法可能對應(yīng)后臺兩個請求接口,所以請求參數(shù)就會有所不同。需要我們先設(shè)置共同的參數(shù),然后根據(jù)條件動態(tài)添加參數(shù)屬性2022-08-08
Vue實(shí)現(xiàn)天氣預(yù)報(bào)功能
這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)天氣預(yù)報(bào)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
Vue3使用vue-router如何實(shí)現(xiàn)路由跳轉(zhuǎn)與參數(shù)獲取
這篇文章主要介紹了Vue3使用vue-router如何實(shí)現(xiàn)路由跳轉(zhuǎn)與參數(shù)獲取,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03
Vue實(shí)例初始化為渲染函數(shù)設(shè)置檢查源碼剖析
這篇文章主要為大家介紹了Vue實(shí)例初始化為渲染函數(shù)設(shè)置檢查源碼剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
vue項(xiàng)目創(chuàng)建并引入餓了么elementUI組件的步驟
這篇文章主要介紹了vue項(xiàng)目創(chuàng)建并引入餓了么elementUI組件的步驟,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-04-04
Vue.js 2.0窺探之Virtual DOM到底是什么?
大家可能聽說Vue.js 2.0已經(jīng)發(fā)布,并且在其中新添加如了一些新功能。其中一個功能就是“Virtual DOM”。那么下面這篇文章就來給大家詳細(xì)介紹Vue.js 2.0中的Virtual DOM到底是什么?需要的朋友可以參考借鑒,下面來一起看看吧。2017-02-02

