移動端滑動穿透事件,支持ios、Android

直奔主題,這兩天我負責開發的app內容遇到了一個問題:彈框底層頁面還是能滑動問題(在Android和ios12系統一下是正常的,ios高版本可滑動)也就是我們所說的滑動穿透事件          

我遇到的兩種情況:

第一種:如圖(當彈框中內容不需要滑動

遇到這種情況網上一頓找,看看是什麼原因造成的。說簡單點就是滑動穿透事件造成

滑動穿透事件:有一層遮罩蒙層覆蓋在body上時,當我們滾動遮罩層,它下面的內容也會跟着一起滾動,看起來好像是上面的滾動事件穿透到下面的DOM元素上一樣,我們稱之爲滾動穿透。

解決辦法網上有幾種:(個人知道的三種:position:fixed方法、禁止滾動事件方法、引入iscroll.js方法)

一、position:fixed方法(我並沒有用這種方法,原因:

1:我開發的是成熟的app避免改動過大、涉及到改動的都要再測試一遍,麻煩。

2:移動端不引入其他庫的情況下處理的。其實在移動端寫彈窗,內部滑動問題通過overflow:scroll解決不完美,安卓ios總之是會有一些問題的。)

1.當出現彈窗的時候,給body設置爲 position:fixed;overflow:hidden;

2.關閉彈窗的時候,給body的這兩個屬性去掉。

注:這個時候你會發現每次關閉彈窗之後,總是在頁面的最頂部。

        因爲出現彈窗的時候,整個body都脫離文檔流了,所以關閉的時候肯定是以當前手機的最頂部爲基準的 ,

我是這樣解決的:每次點擊彈窗按鈕的時候,都會記錄一下當前滑動的距離,然後當關閉彈窗的時候,再回到那個位置去,代碼如下:
 

二、禁止滾動事件方法

1.利用禁止滾動:e.preventDefault()

2.用if判斷是否阻止滾動事件

//彈框顯示/隱藏  底部頁面滑動
//passive 參數來兼容各個瀏覽器(ios12系統 默認true)
var canScroll = false;
document.addEventListener('touchmove',function(e){
	if(canScroll){
		e.preventDefault();
	}
},{passive: false})

上述是我的解方法代碼,代碼中addEventListener的第三個參數共有三個、分別是capture: false、passive: false、once: false。三個屬性都是布爾類型的開關,默認值都爲 false

capture:capture 屬性等價於以前的 useCapture 參數。

once:once 屬性就是表明該監聽器是一次性的,執行一次後就被自動 removeEventListener 掉,還沒有瀏覽器實現它。

passive:如果我們是爲了阻止頁面滾動添加了上述代碼,默認行爲就是滾動頁面,但是如果我們阻止了這一默認行爲,瀏覽器是無法預先知道的,必須等待事件監聽器執行完成後,才知道要去阻止默認行爲。等待監聽器的執行是耗時的,,有些甚至耗時很明顯,這樣就會導致頁面卡頓。即便監聽器是個空函數,也會產生一定的卡頓,畢竟空函數的執行也會耗時。所以就有了passive屬性,如果要阻止默認事件可以設置passive:false

到此我面臨的第一種問題已經解決!

然而幾天後開發中有遇到一樣的問題滑動穿透事件,到此我解決過一次以爲能分分鐘解決,下面我們接着說第二種問題。

第二種:如圖(當彈框中內容需要滑動

針對這個彈框我毅然決然的將上次的解決代碼放上去。結果在測試時發現彈框底部頁面不能滑動了就連彈框裏面的內容也不能滑動了,彈框裏面再彈彈框內容也不能滑動了!!!!

採用這種方案帶來的最大的問題是:

所有的滾動事件全部被禁止了!

假如我們的浮層上真的需要滾動事件,就不能阻止這些元素的默認行爲。

滑動穿透解決方法只能用在彈框裏面內容不滑動情況使用。

解決辦法:那就用第三種iscroll.js方法

三、iscroll.js方法

1.Scroll是一個類,每個需要使用滾動功能的區域均要進行初始化。每個頁面上的iScroll實例數目在設備的CPU和內存能承受的範圍內是沒有限制的。儘可能保持DOM結構的簡潔。iScroll使用硬件合成層但是有一個限制硬件可以處理的元素。

<div id="wrapper">
    <ul>
        <li>...</li>
        <li>...</li>
        ...
    </ul>
</div>

iScroll作用於滾動區域的外層。在上面的例子中,UL元素能進行滾動。只有容器元素的第一個子元素能進行滾動,其他子元素完全被忽略。

iscroll.js的初始化方式:

<script type="text/javascript">
    var myScroll = new IScroll('#wrapper'); //初始化
</script>

iscroll.js的銷燬方式:

myScroll.destroy();
myScroll = null;

說起用這個方法那是一個悲傷份故事,推薦大神博文一篇,必能不會讓各路大佬失望。具體的方法和設置參數都介紹到了。我不多扯了。https://blog.csdn.net/amyloverice/article/details/79383712

滑動穿透是解決了,又出現一個問題:當app頁面彈出彈框時有的時候是滑動正常有的時候回影響app的下拉刷新功能。故此有捨棄了此方法。

再次也介紹一位大佬博文:http://www.cnblogs.com/gaohui/p/5819777.html

最後用一個簡單的方法解決了,到現在沒有測試出什麼問題

$('.cue-bg').on('touchmove',function(e) {
   e.preventDefault();
})

$('.cue-bg')是彈框的遮罩層。

以上方法只是解決單一問題。在app中將彈框滑動穿透事件封裝成函數還在進一步學習中...   各位大佬請指正幫忙!感謝

 

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