移动端滚动穿透问题解决

移动端浏览器中,会出现这样一个坑爹的问题:当弹出一个可以滚动的浮层,当滚动浮层到底部直到浮层不能滚动时,这时如果继续滚动,浮层底下的元素会发生滚动。

这种情况,如果单纯的用css,并没有什么好的解决办法,在移动端,可以用js来监听触摸事件,阻止默认行为来解决这个问题了。

为什么不直接阻止默认行为?

举个例子,如果,弹出的浮层元素是可以滚动的,此时阻止之后,浮层内元素也不能继续滚动了,所以,这样做不行。

解决问题的思路

我们可以检测待滚动的元素边界。

1、首先,判断这个元素是不是可以滚动的

2、如果是不可滚动的元素,直接阻止默认行为即可

3、如果是可以滚动的,先检测是否元素已经滚动到顶部并且有向上滚动的行为,如果是,则阻止。

4、如果是可以滚动的,第3步中已经检测了顶部,还应该再检测底部,那么就需要检测是否已经滚动到最底部,并且有继续向下滚动的行为,如果是,则阻止。

5、其余的行为均放行

综合上述思路,实现代码大体如下

const scrollHandler = element => {
  let events

  const data = {
    posY: 0,
    maxScrollDistance: 0
  }

  element.addEventListener('touchstart', function (e) {
    events = e.touches[0] || e

    data.posY = events.pageY
    data.maxScrollDistance = element.scrollHeight - element.clientHeight
  })

  element.addEventListener('touchmove', function (e) {
    events = e.touches[0] || e

    const distanceY = events.pageY - data.posY

    //到达顶部与达到底部阻止
    if (distanceY > 0 && element.scrollTop === 0 || (element.scrollTop === data.maxScrollDistance && distanceY < 0)) {
      e.preventDefault()
    }
  })
}

本文完!:)

如果您觉得本文对您有用,欢迎捐赠或留言~
微信支付
支付宝

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注