我是在pc端 用swiper做了個整屏縱向滑動的效果,(用的框架是vue),雖然是個pc端項目,但是我想盡量的去適配移動端,為了方便期間,我把項目鏈接發送到了微信上,然后在微信里直接點擊頁面鏈接進去了,
這時,問題出現了,我發現當我用手指拖動頁面時,會非常不好使,特別是切換到最底部的一屏時,簡直無法往上拖動切換,我一拖動,整個頁面就往下被拖動了,剛開始不知所措,然后上網查,結果查出了原因,
這是因為,在微信瀏覽器中,瀏覽器沒能很好的分辨出我的拖動是拖動整個文檔頁面,還是拖動swiper里的slide使slide切換,
於是對症下葯:我選擇把body的touchmove事件去掉(所有的子元素的touchmove事件,冒泡到body后都會停止繼續冒泡)
document.body.addEventListener('touchmove' , function(e){
e.preventDefault();
});
這太簡單粗暴了,我自己又兼容了一下代碼
document.body.addEventListener('touchmove' , function(e){
var e=e||window.event;
e.preventDefault();
},false)
在微信瀏覽器上試了一下,拖動已經好使了!!!!
正在興奮之余,我的眼角余光票到了控制台,好像有一段紅字哎????????報錯了????(谷歌瀏覽器)
報錯是:Unable to preventDefault inside passive event listener due to target being treated as passive.
有道詞典翻譯是這樣的:無法防止被動事件偵聽器內部的默認,因為目標被視為被動的
翻譯了也不懂是哪里出錯了,然后把報錯代碼貼到了度娘上,搜到答案了!!!!
大致意思是這樣的:
由於瀏覽器必須要在執行事件處理函數之后,才能知道有沒有掉用過 preventDefault() ,這就導致了瀏覽器不能及時響應滾動,略有延遲。
所以為了讓頁面滾動的效果如絲般順滑,從 chrome56 開始,在 window、document 和 body 上注冊的 touchstart 和 touchmove 事件處理函數,會默認為是 passive: true。瀏覽器忽略 preventDefault() 就可以第一時間滾動了。 舉例: wnidow.addEventListener('touchmove', func) 效果和下面一句一樣 wnidow.addEventListener('touchmove', func, { passive: true })
以下是個人理解:
我想禁止掉touchmove事件,但是只能等到
touchmove事件觸發之后,才會執行我的
preventDefault()。
由於現在谷歌瀏覽器默認
touchstart 和 touchmove 事件處理函數是被動的;也就是
{ passive: true }; passive:被動的
而現在我是調用了
touchmove事件之后才將他禁用的,所以會出現上面的報錯,被動事件不能被阻止。
好了,報錯原因找到了,那我將touchmove事件改成主動的不就行了嘛。。。。。。。
document.body.addEventListener('touchmove' , function(e){
var e=e||window.event;
e.preventDefault();
},
{ passive: false }
)
報錯消失了。。。
成功阻止微信拖動事件!!
網上還有解決辦法:搬過來,占為己有
2、應用 CSS 屬性 touch-action: none;
這樣任何觸摸事件都不會產生默認行為,但是 touch 事件照樣觸發。
touch-action 還有很多選項,詳細請參考touch-action
[注]未來可能所有的元素的 touchstart touchmove 事件處理函數都會默認為 passive: true