移動端開發遮罩層(彈窗)防止滾動穿透解決方案

在移動端頁面開發中,經常會去封裝一個遮罩層(全屏彈窗),遮罩層(全屏彈窗),遮罩層(全屏彈窗)的組件,但是如果是固定定位的position:fixed;在彈出的時候會遇到一些小坑,之前搜索了一下,網上的博客也好評論也罷,總是有點缺陷或者累贅代碼太多。就比如今天的主題,如何防止遮罩層(全屏彈窗)下方body內容繼續滾動呢?

移動端開發遮罩層(彈窗)防止滾動穿透完美解決方案

首先,pc的肯定直接就給body設置一個overflow:hidden的屬性,就完美解決了。

這沒什麼好說的,主要是到手機上,大家會發現給body添加的屬性根本就沒有任何作用,遮罩層(全屏彈窗)出現了該怎麼滑動還是怎麼滑動。

下邊給出三種解決方案:

第一種方案(參考他人的方案):

點擊彈出的時候,給html,body均添加一個overflow:hidden的屬性,這時候你會發現背景已經不會滾動了,但是這樣做有個弊端,那就是當遮罩層(全屏彈窗)消失的時候,頁面就會自動回到了頂部,別人瀏覽一個頁面,點擊完彈窗且消失以後就回到頂部了?顯然不太合理吧。所以在你點擊消失的時候要去記錄一下當前的scrollTop,再賦值給當前頁面的scroll,就算是解決了。這裏不詳細介紹寫法,推薦一個githup的作者有介紹這種方法,點擊查看>>

ps:我本人覺得這種方法也能用,但是代碼太多,接着看下邊的解決方案

第二種方案(適用於簡單彈窗):

直接在遮罩層(彈窗)上添加@touchmove.prevent(這裏是vue中),它的作用就是當你全屏的遮罩層(彈窗)時,就會禁止滑動,原理就是因爲該彈出層都禁止滑動了,自然而然就不存在滑動穿透的問題了,是不是很簡單粗暴?我們想做的更好一點就是給body再添加一個overflow:hidden的屬性,這樣出了人爲的手動滑動不能意外,其他工具的滑動也不能執行了(鼠標)

<div class="box" v-if="tan" @click="close" @touchmove.prevent></div>
document.body.classList.add('overflow-hidden');
.overflow-hidden{
    overflow: hidden;
}
.box{
    width: 100%;
    height:100%;
    position: fixed;
    top: 0;
    background: rgba(0,0,0,0.8);
}

第三種方案(適用於封裝組件,彈出時內容區域滾動可控制的複雜情景):

點擊彈窗的時候,監聽touchmove事件,並禁止。

點擊消失的時候,監聽同樣的事件,remove刪除。

這樣做的好處是,結構中沒有直接禁用滑動事件,而是通過指令進行控制,更加適合開發所需。

click(){//點擊彈窗
    this.tan=true
    document.body.classList.add('overflow-hidden');
    document.addEventListener('touchmove', this.touchStart,{passive:false});//一般第三個參數可直接填false,true -> 表示在捕獲階段調用事件處理程序, false -> 表示在冒泡階段調用事件處理程序使用,但是touchmove會被瀏覽器忽略掉,並不會阻止默認行爲,這裏通過passive:false明確聲明爲不是被動的
},
touchStart(){
    event.preventDefault();//通知 Web 瀏覽器不要執行與事件關聯的默認動作
},
close(){//點擊關閉彈窗
    this.tan=false
    document.body.classList.remove('overflow-hidden');
    document.removeEventListener('touchmove',this.touchStart,{passive:false});
}

你學會了嗎?幫到你的點個贊加個關注哦,不會的或者沒看懂的歡迎留言。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章