最近在用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 } }