摘要:場景當頁面出現浮層的時候,滑動浮層的內容,正常情況下預期應該是浮層下邊的內容不會滾動然而事實并非如此。當屬性的值為的時候,代表該監聽器內部不會調用函數來阻止默認滑動行為,瀏覽器稱這類型的監聽器為被動監聽器。
場景
當頁面出現浮層的時候,滑動浮層的內容,正常情況下預期應該是浮層下邊的內容不會滾動;然而事實并非如此。
如圖所示,浮層下邊的內容并沒有如想象中不受影響。
先去github上搜索一番,發現有解決此問題的開源包,簡單粗暴直接挑選了其中star的最高的(body-scroll-lock)操作一番!
使用后發現有一些問題:
安卓端全掛
ios端偶爾會有鎖不住的情況
查源碼發現該包在iOS端使用禁止touchmove的方式多帶帶處理,但是在其他端只是給body加overflow: hidden簡單處理。
于是決定寫一個針對多端通用的包來處理類似的問題。
看到下邊的滾動肯定立刻就想到了是整個viewport的滾動,那么如果給body設置overflow: hidden,此時body的內容就只有一屏了,肯定不會滾動了;
body { overflow: hidden; }
此方案在pc端完美解決了我們的問題,然而事情并沒有那么簡單;
再試試移動端:
移動端中并沒有出現期待的效果。。。
既然pc端已經有了完美的方案,下邊我們繼續探索移動端的解決方案。
上邊想到給body設置overflow: hidden在移動端并不能解決我們的問題,是否在于body的height沒有設置
將html、body的高度都設置為100%;
給body設置絕對定位(fixed);
同時使用這兩個操作似乎完美滿足了我們的需求;
但是如圖所示,每次都會將頁面拉到最頂上的位置,這樣看起來又不完美了;
既然使用了定位,那么給一個top值不就定位到我們想要的位置了(聰明如我)。
tips: body 設置 relative 定位會頁面自身拉上去,下邊留白
多次實驗發現這個方案在android端中完美達到了我們想要的結果,但是在ios端并不理想;每次定位的時候會有閃動的問題;好事多磨,接著探索ios端的方案。
探索三:禁止touchmove如果禁止掉頁面的touchmove是否可行呢?話不多說就是干!
當彈出浮層的時候禁掉頁面元素的touchmove
document.addEventListener("touchmove", function (event) { event.preventDefault() })
測試發現沒有達到想象中的效果,感覺這個結果并不能接受啊,禁止document 的touchmove都不能禁止滾動的嗎?
進一步的探索后發現原因竟是這個屬性
passive addEventListener第三個參數中傳入
原來是瀏覽器做的一些優化,chrome passive-event-listeners
Passive Event Listeners是Chrome提出的一個新的瀏覽器特性:Web開發者通過一個新的屬性passive來告訴瀏覽器,當前頁面內注冊的事件監聽器內部是否會調用preventDefault函數來阻止事件的默認行為,以便瀏覽器根據這個信息更好地做出決策來優化頁面性能。當屬性passive的值為true的時候,代表該監聽器內部不會調用preventDefault函數來阻止默認滑動行為,Chrome瀏覽器稱這類型的監聽器為被動(passive)監聽器。
知道問題就好說了,給addEventListener傳入第三個參數
document.addEventListener("touchmove", function (event) { event.preventDefault() }, { passive: false })
大功告成!
突然想到,如果浮層中還需要滾動那就不GG了!
so,是不是可以有選擇性的禁止滾動(在浮層中元素滾動到最頂部或者最底部之后禁止滾動)。
多帶帶處理浮層中需要滾動的元素;
targetElement.ontouchmove = function (event) { const clientY = event.targetTouches[0].clientY - initialClientY if (targetElement && targetElement.scrollTop === 0 && clientY > 0) { return preventDefault(event) } if (targetElement && (targetElement.scrollHeight - 1 - targetElement.scrollTop <= targetElement.clientHeight) && clientY < 0) { return preventDefault(event) } event.stopPropagation() return true }
這個方案在ios中完美實現,但是在 android中還是有一點問題;浮層內容拉到最頂部或者最底部的時候依然會帶動頁面的內容有一定程度的移動。
終極方案來啦!
tua-body-scroll-lock即是在ios、android和PC各個端多帶帶處理,保證在每個端都可以實現完美的效果!
demo
安裝$ npm i -S tua-body-scroll-lock # OR $ yarn add tua-body-scroll-lock使用
import { lock, unlock } from "tua-body-scroll-lock" // 禁止滑動后還需要內部可以滾動的元素(針對移動端ios處理) const targetElement = document.querySelector("#someElementId"); lock(targetElement) unlock(targetElement)
tips: PC端不需要targetElement, 不傳targetElement也不想要控制臺提示可以傳null
import { lock, unlock } from "tua-body-scroll-lock" lock() unlock()
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/103754.html
摘要:場景當頁面出現浮層的時候,滑動浮層的內容,正常情況下預期應該是浮層下邊的內容不會滾動然而事實并非如此。當屬性的值為的時候,代表該監聽器內部不會調用函數來阻止默認滑動行為,瀏覽器稱這類型的監聽器為被動監聽器。 場景 當頁面出現浮層的時候,滑動浮層的內容,正常情況下預期應該是浮層下邊的內容不會滾動;然而事實并非如此。showImg(https://user-gold-cdn.xitu.io...
摘要:接下就說下我對滾動穿透問題解決方案探索的過程,希望對大家有點啟發。心想來了突然意識到寫彈窗的時候忘記處理滾動穿透的問題了。下期預告前端詞典繼承必懂知識點傳送門前端詞典代理的概念及其應用前端詞典滾動穿透問題的解決方案 背景 產品有三寶,彈窗,浮層加引導; 設計有三寶,透明,陰影加圓角; 運營有三寶,短信,推送加紅包; 程序員有一寶,這個做不了。 隨著移動端市場的份額越大,需求就越多...
摘要:接下就說下我對滾動穿透問題解決方案探索的過程,希望對大家有點啟發。心想來了突然意識到寫彈窗的時候忘記處理滾動穿透的問題了。下期預告前端詞典繼承必懂知識點傳送門前端詞典代理的概念及其應用前端詞典滾動穿透問題的解決方案 背景 產品有三寶,彈窗,浮層加引導; 設計有三寶,透明,陰影加圓角; 運營有三寶,短信,推送加紅包; 程序員有一寶,這個做不了。 隨著移動端市場的份額越大,需求就越多...
摘要:問題眾所周知,移動端當有遮罩背景和彈出層時,在屏幕上滑動能夠滑動背景下面的內容,這就是著名的滾動穿透問題之前搜索了一圈,找到下面兩種方案之頁面彈出層上將添加到上,禁用和的滾動條但是這個方案有兩個缺點由于和的滾動條都被禁用,彈出層 問題 眾所周知,移動端當有 fixed 遮罩背景和彈出層時,在屏幕上滑動能夠滑動背景下面的內容,這就是著名的滾動穿透問題 之前搜索了一圈,找到下面兩種方案 c...
摘要:所以這種情況下是不符合點擊事件的定義的。,關于移動端的點擊事件總結完了,可能你都沒想到一個簡單的點擊事件會有那么多坑,如果你在工作中可能會涉及到移動端開發的話,相信這篇文章還是值得你點贊和收藏的,畢竟是踩了那么多坑的經驗總結。 看標題的時候你可能會想,點擊事件有什么好說的,還寫一篇攻略?哈哈,如果你這么想,只能說明你too young to simple. 接觸過移動端開發的同學可能都...
閱讀 1200·2021-11-24 11:16
閱讀 3428·2021-11-15 11:38
閱讀 1920·2021-10-20 13:47
閱讀 546·2021-09-29 09:35
閱讀 2192·2021-09-22 15:17
閱讀 1013·2021-09-07 09:59
閱讀 3374·2019-08-30 13:21
閱讀 2904·2019-08-30 12:47