vue 盒子滾動(dòng)吸頂效果的實(shí)現(xiàn)

在優(yōu)化項(xiàng)目的時(shí)候, 產(chǎn)品提出需求需要在頁面滾動(dòng)到當(dāng)前元素下面的時(shí)候, 此元素自動(dòng)固定到頁面最頂部, 就是類似于百度的吸頂效果,如圖


百度搜索打開進(jìn)入時(shí)


吸頂效果

話不多算,直接上干貨:

? ?你在網(wǎng)上找到的一般是這樣的實(shí)現(xiàn)代碼


通過監(jiān)聽body向上卷起的距離動(dòng)態(tài)的給目標(biāo)元素添加固定定位的css屬性

但是:

這樣的代碼能實(shí)現(xiàn)需求嗎?? ?并不能, 在移動(dòng)端可以,但是在PC端不行的

我就試著寫了一個(gè)原生的demo,發(fā)現(xiàn)原生的是可以實(shí)現(xiàn)需求的,因?yàn)槲覀兪莢ue項(xiàng)目,所以這里就不重點(diǎn)體現(xiàn);


解決方案(免費(fèi))

最終通過很久的研究,實(shí)現(xiàn)了需求:

使用?obj.getBoundingClientRect().top?

定義:這個(gè)?API?可以告訴你頁面中某個(gè)元素相對瀏覽器視窗上下左右的距離。

使用:tab 吸頂可以使用?obj.getBoundingClientRect().top?代替?scrollTop - offsetTop,代碼如下:

//css

.isFixed{

? ? ? ? position: fixed;

? ? ? ? top: 60px;//自己根據(jù)需求設(shè)定

? ? ? ? z-index: 999;

? ? ? ? width: 100%;

? ? }

// html

<div class="container" ref="fixedHeaderRoot" id="fixedHeaderRoot"?>

? ? <div class="title-box" :class="headerFixed== true ? 'isFixed' :''">

? ? ? ? // some code

? ? </div>

</div>

// vue

export default {

? ? data(){

? ? ? return{

? ? ? ? headerFixed: false

? ? ? }

? ? },

? ? created() {//// 事件監(jiān)聽滾動(dòng)條

? ? ? this.headerFixed= false;

? ? ? window.addEventListener('scroll', this.handleScroll,true)//建議第三個(gè)參數(shù)為true,我原來沒有設(shè)置導(dǎo)致沒有深度監(jiān)聽

? ? },

? ? methods: {

? ? ? //主要處理函數(shù), 判斷目標(biāo)元素吸頂?shù)臅r(shí)機(jī)

? ? ? handleScroll () {

? ? ? ? let offsetTop = this.$refs.fixedHeaderRoot.getBoundingClientRect().top;

? ? ? ? this.headerFixed = offsetTop<0?true:false

? ? ? ? // some code

? ? ? }

? ? },

? }

實(shí)現(xiàn)方法也是通過動(dòng)態(tài)給目標(biāo)元素增加固定定位的屬性, 相信仔細(xì)研究,一眼你就能明白

但是.你以為這樣就結(jié)束了,你會(huì)發(fā)現(xiàn)


有時(shí)好的,有時(shí)報(bào)錯(cuò)

這是為什么呢,可能滾動(dòng)的太頻繁,頁面還沒有重新加載到? this.$refs;所以,我的解決辦法想當(dāng)?shù)暮唵?

//css

.isFixed{

? ? ? ? position: fixed;

? ? ? ? top: 60px;//自己根據(jù)需求設(shè)定

? ? ? ? z-index: 999;

? ? ? ? width: 100%;

? ? }

// html

<div class="container" ref="fixedHeaderRoot" id="fixedHeaderRoot"??>? ?

????<div class="title-box" :class="headerFixed== true ? 'isFixed' :''">? ? ? ?

????// some code? ?

????</div>

</div>

// vue

export default {

? ? data(){

? ? ? return{

? ? ? ? headerFixed: false

? ? ? }

? ? },

? ? created() {//// 事件監(jiān)聽滾動(dòng)條

? ? ? this.headerFixed= false;

? ? ? window.addEventListener('scroll', this.handleScroll,true)//建議第三個(gè)參數(shù)為true,我原來沒有設(shè)置導(dǎo)致沒有深度監(jiān)聽

? ? },

? ? methods: {

? ? ? //主要處理函數(shù), 判斷目標(biāo)元素吸頂?shù)臅r(shí)機(jī)

? ? ? handleScroll () {

? ? ? ? let offsetTop = this.$refs.fixedHeaderRoot.getBoundingClientRect().top;

????????let offsetTop = this.$el.querySelector('#fixedHeaderRoot').getBoundingClientRect().top;

? ? ? ? this.headerFixed = offsetTop<0?true:false

? ? ? }

? ? },

? ??????destroyed() {//組件銷毀時(shí)解除監(jiān)聽

????????????window.removeEventListener("scroll", this.handleScroll);

????????},

}

在使用中發(fā)現(xiàn)如下報(bào)錯(cuò):


api為null

經(jīng)過排查發(fā)現(xiàn)是路由改變組價(jià)銷毀,但其實(shí)頁面并沒有關(guān)閉, 此時(shí)我們已經(jīng)解除了滾動(dòng)監(jiān)聽, 所以報(bào)Cannot read property 'getBoundingClientRect' of null

所以, 取消生命周期(銷毀后的解除滾動(dòng)監(jiān)聽)

//組件銷毀時(shí)解除監(jiān)聽?

destroyed() {? ? ? ? ? ?????window.removeEventListener("scroll", this.handleScroll);????????},


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容