移動端和PC端彈出遮罩層后,頁面禁止滾動的解決方法及探究


PC端解決方案

pc端的解決思路就是在彈出遮罩層的時候取消已經存在的滾動條,達到無法滾動的效果。

也就是說給body添加overflow:hidden屬性即可,IE6、7下不會生效,需要給html增加overflow:hidden屬性。

 

要制作這個效果在PC端非常簡單,只需要設置html的高度為100%占滿屏幕,並且將html的overflow設置為hidden,即可保證頁面不可滾動。

但是同樣的問題在移動端情況就有所區別。僅僅設置html的上列屬性,在移動端仍然無法禁止頁面超出部分的滾動,我們需要設置下面的代碼才能在彈框出現的時候禁止頁面滾動:

 

html.style.overflow="hidden";

html.style.height="100%";

body.style.overflow="hidden";

body.style.height="100%";

 

原因是因為移動端是基於touch事件,要禁止基於touch事件的滾動,我們必須在對html禁止滾動的基礎之上,再將需要禁止滾動的內容上再增加一個包裹層塊級元素,然后將這個包裹層塊級元素高度設置為100%並設置overflow:hidden;,那么在這里我們認為body包裹了整個頁面,正是我們需要的塊級元素,將他也設置為禁止滾動,就可以保證移動端頁面的滑動時間不會觸發頁面滾動。

當用戶關閉了彈框,頁面也就恢復正常,我們設置如下CSS樣式屬性來還原整個頁面的滾動效果:

 

html.style.overflow="visible";

html.style.height="auto";

body.style.overflow="visible";

body.style.height="auto";

 

這些樣式正是對應CSS屬性的默認樣式。

然而這個方案有一個缺陷,就是ios系統下不兼容,黑幕的效果沒法阻止頁面的滾動。下面介紹移動端的另一種解決方案。

 

 

移動端解決方案

正是因為移動端的滾動基於屏幕的touch事件,因此誕生了方案二(手機淘寶就使用了這種方案)。

首先我們需要知道兩個前提知識點:1、重疊的兩個頁面元素,z-index值更高的會優先觸發事件監聽,從而可以在此控制是否讓事件流繼續;2、移動端滾動的touch事件,基於事件流。

有了上面兩個知識點的基礎,我們就可以來理解這種方案的設計思路。方案二的原理是:不對原頁面進行任何改動,僅僅只是用一個擁有更高z-index值的,布局為absolute或者fixed布局的黑幕(長寬100%)來擋住整個頁面,並且監聽黑幕的touchmove事件,在touchmove事件內結束事件流,從而阻擋事件流繼續。這樣,能夠產生滾動效果的touch事件就傳不到頁面上,也就不會發生滾動。

 

移動端取消滾動條是達不到效果的,這時就需要去除遮罩層和按鈕層的touchmove的默認事件,代碼如下:

 mask.addEventListener("touchmove",function(e){

                    e.stopPropagation();

                    e.preventDefault();

                },false);

 

后來我把e.stopPropagation()注釋了,沒有禁止事件冒泡,在遮罩彈出后touchmove以為頁面應該會滾動,但是頁面還是不滾動。然后我在頁面加了

document.getElementsByTagName(‘body’)[0].addEventListener("touchmove", function(){
   alert(‘hello’);
})

;遮罩彈出后,手指touchmove滑動頁面不會滾動,但是會alert(‘hello’);,說明事件還是冒泡了,只是touchmove沒有傳到頁面上。猜測可能是這個原因,touchmove事件只針對第一次觸發的最上層的容器,而不會冒泡傳遞。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM