h5 解决局部区域滑动 触发整体窗口下拉

1,399 阅读2分钟

需求:

  1. 禁止h5内部、区域滑动触发整个页面弹性下拉,
  2. 内部滑动与窗口下拉事件冲突(内部虚拟滑动时,总是触发系统页面下拉),无法正常交互

问题剖析:

微信下拉弹性效果其实是浏览器本身的一种特性,当不做任何处理时,达到某个时机,浏览器会认为可以触发整个页面弹性下拉。如果想禁止整个页面的下拉回弹,可以通过下面几种方式实现。

方式1

touch-action: none; 

阻止了所有事件

方式2

类似这种暴力方式 会解决某一区域滑动阻止触发 整个页面弹性下拉

document.body.addEventListener('touchmove', 
  function (e) {
    e.preventDefault()
  }, 
{ passive: false })
特点: 简单粗暴直接
弊端: 
	1. 如果全局给body处理,过于直接,如果其他区域存在内部滑动,导致相应区域失效 
	2. React事件绑定无法通过onTouchMove event.preventDefault() 解决,没有提供类似VUE v-on:touchmove.prevent 。。。需要手动addEventListener + { passive: false } 绑定处理

方式3 区域滚动或者区域虚拟滚动

滚动区域 A , A区域的包裹层 AWrapper AWrapper绑定touchmove, touchstart, touchend 事件,处理触摸滚动操作A的展示区域。

当A 滚动到顶部(AWrapper.scrollTop === 0) 继续向下touchmove,浏览器会触发祖先元素滚动,直至会出现页面弹性下拉。

可以在A 与 AWapper中间增加一层 AParent 区域,此区域比AWrapper 高度偏高1~2px即可

原始处理绑定方式不变,只需要在touch事件中设置保持AWrapper.scrollTop = 1px 即可! 
不管内部滚动到顶部或是什么位置[AParent:overflow:auto方式](或者监听touch偏移后 translateY 的 虚拟滚动 [AParent:overflow:hidden方式]),都不会触发页面滚动, 且AParent 1px偏移基本不会对视觉产生影响!!