vue解決彈出蒙層滑動(dòng)穿透問題的方法
最近開發(fā)過程中遇到一些小問題(似乎問題總是那么多),但一直沒什么時(shí)間去優(yōu)化與解決。程序員不能被業(yè)務(wù)綁架,有時(shí)間還是花點(diǎn)在代碼上😀,開始這次的vue嘗試吧。
【遇到的問題】
在一個(gè)可滑動(dòng)列表頁彈出一個(gè)全屏蒙層,蒙層固定,中間一塊顯示消息框,當(dāng)用手滑動(dòng)蒙層空白處時(shí),滑動(dòng)事件會(huì)穿透到底部列表頁,導(dǎo)致列表頁的滑動(dòng)。
【要實(shí)現(xiàn)的目標(biāo)】
1. 滑動(dòng)蒙層空白處不讓滑動(dòng)事件穿透?! ?/p>
2. 當(dāng)蒙層消息框文字多時(shí),要讓文字可上下滑動(dòng)。
要實(shí)現(xiàn)的效果其實(shí)如下:

【實(shí)現(xiàn)思路】
1. vue提供的@touchmove.prevent可以用來阻止滑動(dòng),但是這個(gè)方法會(huì)對其內(nèi)的子div的滑動(dòng)事件也禁止掉了,這樣會(huì)導(dǎo)致中間文字無法滑動(dòng)。如果沒有中間滑動(dòng)需求,用@touchmove.prevent實(shí)現(xiàn)是一個(gè)很好的方法。
2. 蒙層設(shè)為fixed懸浮在最上,底部列表設(shè)置overflow-y: hidden;這樣可以列表內(nèi)容就不可以滑了,但實(shí)際過程中沒有效果,于是想到繼續(xù)往列表父div向上追溯,對body和html標(biāo)簽設(shè)置相關(guān)樣式,這樣就控制住了底部列表滑動(dòng)問題。
3. 蒙層空白處點(diǎn)擊事件與中間文字點(diǎn)擊事件處理,防止事件冒泡帶來其他bug。
【相關(guān)實(shí)現(xiàn)代碼】
1. html代碼都是比較簡單,列表頁for循環(huán)實(shí)現(xiàn);蒙層用一個(gè)變量控制其顯示和隱藏。但這里有幾個(gè)注意點(diǎn): a. 給上面列表的div動(dòng)態(tài)綁定了noScroll class,它的作用是當(dāng)消息蒙層顯示時(shí)切換到相關(guān)的css樣式; b. 彈出的全屏蒙層,加有點(diǎn)擊事件是為了點(diǎn)空白處讓蒙層消失,但這里對顯示的每行文字還加了@click.stop="messageTitleClick(num)"這個(gè)方法,為什么加它呢——是因?yàn)槊蓪涌瞻滋幍狞c(diǎn)擊方法對整個(gè)蒙層都生效,在文字上加上這個(gè)方法可以屏蔽掉蒙層點(diǎn)擊方法的影響,即使這個(gè)方法里什么也不做它也是有作用的,另外這個(gè)方法上加了stop是為了防止它的點(diǎn)擊事件穿透到后面的div。代碼如下:
<!-- 列表 -->
<div :class="{noScroll: isShowPopup}">
<div class="item" v-for="num in 50" @click="itemClick(num)">
<div style="width:100%">點(diǎn)擊item{{num}}</div>
</div>
</div>
<!-- 蒙層 -->
<div v-if="isShowPopup" class="popup" @click="popUpEmptyClick()">
<div class="message">
<p class="message-title" v-for="num in 30" @click.stop="messageTitleClick(num)">
消息提示 {{num}}
</p>
</div>
</div>
2. 給整個(gè)列表動(dòng)態(tài)綁定的css如下
/* 當(dāng)前蒙層顯示時(shí)生效 */
.noScroll {
overflow-y: hidden;
}
3. 給列表整個(gè)div動(dòng)態(tài)綁定.noScroll 后,底部列表照樣可以滑動(dòng),所以考慮繼續(xù)向上追溯。利用watch監(jiān)聽蒙層是否顯示,當(dāng)顯示時(shí),設(shè)置body相應(yīng)樣式;但蒙層消失時(shí),body樣式恢復(fù)。但是在vue里怎么操作body里,雖然vue是數(shù)據(jù)驅(qū)動(dòng)的,不提倡直接操作Dom。但此刻我也是沒什么好辦法了,就直接操作Dom了。如下:
watch: {
isShowPopup(newVal, oldVal) {
if (newVal == true) {
let cssStr = "overflow-y: hidden; height: 100%;";
document.getElementsByTagName('html')[0].style.cssText = cssStr;
document.body.style.cssText = cssStr;
} else {
let cssStr = "overflow-y: auto; height: auto;";
document.getElementsByTagName('html')[0].style.cssText = cssStr;
document.body.style.cssText = cssStr;
}
// 下面需要這兩行代碼,兼容不同瀏覽器
document.body.scrollTop = this.pageScrollYoffset;
window.scroll(0, this.pageScrollYoffset);
}
}
【補(bǔ)充】
最好去查看完整的demo代碼,因?yàn)楹罄m(xù)代碼對真機(jī)上一些滑動(dòng)問題進(jìn)行了修復(fù)補(bǔ)充,包括處理一些滾動(dòng)條位置等。
【Demo地址】
手動(dòng)將路由切到 /three 就是此頁示例
https://github.com/LiJinShi/wechat_back_vue
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Vite創(chuàng)建項(xiàng)目的實(shí)現(xiàn)步驟
隨著 Vite2 的發(fā)布并日趨穩(wěn)定,現(xiàn)在越來越多的項(xiàng)目開始嘗試使用它。本文我們就介紹了Vite創(chuàng)建項(xiàng)目的實(shí)現(xiàn)步驟,感興趣的可以了解一下2021-07-07
VUE腳手架框架編寫簡潔的登錄界面的實(shí)現(xiàn)
本文主要介紹了VUE腳手架框架編寫簡潔的登錄界面的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08
詳解在Vue.js編寫更好的v-for循環(huán)的6種技巧
這篇文章主要介紹了詳解在Vue.js編寫更好的v-for循環(huán)的6種技巧,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
Vue3-KeepAlive,多個(gè)頁面使用keepalive方式
這篇文章主要介紹了Vue3-KeepAlive,多個(gè)頁面使用keepalive方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08
vue項(xiàng)目打包后網(wǎng)頁的title亂碼解決方案
這篇文章主要介紹了vue項(xiàng)目打包后網(wǎng)頁的title亂碼解決方案,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
Vue項(xiàng)目開發(fā)實(shí)現(xiàn)父組件與子組件數(shù)據(jù)間的雙向綁定原理及適用場景
在 Vue.js 中,實(shí)現(xiàn)父組件與子組件數(shù)據(jù)之間的雙向綁定,可以通過以下幾種方式,下面我將介紹幾種常見的方法,并解釋它們的實(shí)現(xiàn)原理和適用場景,感興趣的朋友跟隨小編一起看看吧2024-12-12
vue+elementUI中el-radio設(shè)置默認(rèn)值方式
這篇文章主要介紹了vue+elementUI中el-radio設(shè)置默認(rèn)值方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12

