最近在用vue寫m端項目時發現個問題,better-scroll的橫向滑動和UC瀏覽器的橫向滑動翻頁效果出現了衝突。html
簡單的說,就是滑動scroll組件的時候也會觸發UC瀏覽器自帶的翻頁效果。vue
爲此在網上找了很多資料,目前網上出現最多的解決方案是使用history.pushState(),使用監聽事件,監聽到跳頁事件(popstate)時,手動填充路徑爲當前頁面地址。瀏覽器
示例代碼以下(引用):app
history.pushState(null, null, document.URL);
window.addEventListener('popstate', function () {
history.pushState(null, null, document.URL);
});
可是我我的在使用的時候發現了另一個問題,這個代碼不太符合個人需求場景,我只須要在scroll橫向滑動禁止翻頁,這個代碼至關於將全部跳頁操做禁止了。this
因而我在這個基礎上作了些一點改動,首先監聽滑塊的滑動,而後在滑塊滑動的時候再去調用history.pushState,這樣在scroll滑動的時候就阻止了UC瀏覽器的默認翻頁。可是這樣又引起另一個問題,瀏覽器history的前進和後退是依靠的是瀏覽歷史的隊列,調用 history.pushState(null, null, document.URL) 就至關於往當前隊列插入了一個當前頁的歷史記錄。這樣的話,每次使用瀏覽器自帶的前進後退功能的時候都須要連續觸發不少次才能跳出當前頁,這樣對於用戶來講顯然是不合理的。code
咱們雖然不能禁止瀏覽器的跳轉操做,可是咱們能夠阻止滑動元素觸發的全部默認事件啊。而後只須要判斷在何時去阻止默認事件以及恢復默認事件就行了。而後也不會影響點擊等操做。htm
<div @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd"> </div>
data() { return { isTouchMove: true, startX: 0, startY: 0, endX: 0, endY: 0, isPreventDefault:false }; }
methods: { touchStart(e){ // 獲取初始位置 this.startX = e.touches[0].clientX; this.startY = e.touches[0].clientY; // 記錄是否進入過touchMove this.isTouchMove = true; }, touchMove(e){ // 若是是UC瀏覽器 而且第一次滑動執行時 if (this.isTouchMove && this.isUC()) { this.endX = e.touches[0].clientX; this.endY = e.touches[0].clientY; // 判斷滑動方向 橫向 | 垂直 if (Math.abs(this.endX - this.startX) > Math.abs(this.endY - this.startY)) { // 若是滑動爲橫向,那麼禁止全部默認事件 // 必要!不然會影響縱向頁面的滾動 e.preventDefault() // 用來輔助判斷是否已經禁止過默認事件 this.isPreventDefault = true; } // 關閉處理邏輯 touchMove連續觸發就不必再進來了 this.isTouchMove = false; } }, touchEnd(e){ // 若是已經禁止過默認事件 那麼恢復默認事件 if(this.isPreventDefault && this.isUC() && e.preventDefault ){ // 恢復默認事件 e.preventDefault() this.isPreventDefault = false; } }, isUC(){ // 判斷是否UC瀏覽器 return navigator.appVersion.indexOf('baidubrowser') !== -1 } }