防止微信H5下拉出现域名究极解决方案

背景:最近在微官网项目时,有一个优化问题,需要阻止微信H5页面下滑时背景出现域名,在网上查到的解决方法大多数是直接阻止掉touchmove的默认事件,如下:

document.addEventListener('touchmove', function (evt) {
    evt.preventDefault()
}, { passive: false })

这样确实阻止掉了touchmove的默认事件,但如果页面中有元素需要滚动,而这个滚动又是基于overflow属性进行设置的,那这个滚动同样也就不能触发了。
然后呢,又在网上一通搜索,发现可以针对性的对元素阻止touchmove默认事件,
如下:

var overscroll = function(el) {
  el.addEventListener('touchstart', function() {
    var top = el.scrollTop
      , totalScroll = el.scrollHeight
      , currentScroll = top + el.offsetHeight;
    if(top === 0) {
      el.scrollTop = 1;
    } else if(currentScroll === totalScroll) {
      el.scrollTop = top - 1;
    }
  });
  el.addEventListener('touchmove', function(evt) {
    if(el.offsetHeight < el.scrollHeight)
      evt._isScroller = true;
  });
}

//下面一行代码就是防止元素被禁用掉touchmove的默认事件的,对于通过使用overflow进行滑动的元素使用

overscroll(document.querySelector('.scroll'));
document.body.addEventListener('touchmove', function(evt) {
  if(!evt._isScroller) {
    evt.preventDefault();
  }
})

以上方法可行,很不错,但对于一个已经成型的项目,且有大量元素使用overflow进行滚动的项目来说,要去进行一一排查,工作量无疑是大的,且有可能会有遗漏的元素。
因此,我再以上的基础上,对这个方法进行了完善。

//该方法用来遍历元素,遍历至根元素,查看每一个元素上的overflow属性是否设置滚动,
//针对设置了滚动的元素调用overscroll方法
function toRoot (dom) {
  const isScroll = window.getComputedStyle(dom, null).overflow
  // console.log(isScroll, dom)
  if (dom.className === 'el-table__fixed') {
    return
  }
  if (isScroll.includes('auto') || isScroll.includes('scroll')) {
    overscroll(dom)
    // return
  }
  if (dom.getAttribute('id') === 'app') {
    return
  }
  if (dom.tagName === 'BODY') {
    return
  }
  toRoot(dom.parentNode)
}
export const overscroll = function (el) {
    //以下属性是用来判断手指滑动的方向,毕竟有的元素只能左右滑,有的元素只能上下滑
  let startX, startY, moveEndX, moveEndY, X, Y
  el.addEventListener('touchstart', function (e) {
    startX = e.touches[0].pageX
    startY = e.touches[0].pageY
    const top = el.scrollTop
    const totalScroll = el.scrollHeight
    const currentScroll = top + el.offsetHeight
    if (top === 0) {
      el.scrollTop = 1
    } else if (currentScroll === totalScroll) {
      el.scrollTop = top - 1
    }
  })
  el.addEventListener('touchend', (e) => {
    moveEndX = 0
    moveEndY = 0
  })
  el.addEventListener('touchmove', function (evt) {
    if (!moveEndX && !moveEndX) {
      moveEndX = evt.changedTouches[0].pageX
      moveEndY = evt.changedTouches[0].pageY
      X = moveEndX - startX
      Y = moveEndY - startY
      console.log(X, Y, moveEndX, startX, moveEndY, startY)
    }
    if (el.offsetHeight < el.scrollHeight && Math.abs(Y) > Math.abs(X)) {
      evt._isScroller = true
    }
    if (el.offsetWidth < el.scrollWidth && Math.abs(X) > Math.abs(Y)) {
      evt._isScroller = true
    }
  })
}
document.addEventListener('touchstart', function (evt) {
  const isScroll = window.getComputedStyle(evt.target, null).overflow
  const dom = evt.target
  if (isScroll.includes('auto') || isScroll.includes('scroll')) {
    overscroll(dom)
    return
  }
  toRoot(dom.parentNode)
}, { passive: false })
document.addEventListener('touchmove', function (evt) {
  if (!evt._isScroller) {
    evt.preventDefault()
  }
}, { passive: false })

将以上代码,用在项目的main.js中,即可解决掉微信H5下拉出现域名的问题,当然,这个方法好像也不能完全的阻止下拉出现域名的问题,当页面未加载完,或者连续快速滑动时,也会导致,但能够极大的减少95%的下拉问题。

ps:如有不足和优化,请在评论区指出

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值