NervJS/taro

onTouchMove不能阻止滑动穿透问题

ItxiaoDz opened this issue · 14 comments

问题描述
我们在做应用时,需要做一个自定义弹窗,带背景蒙层的。使用这个自定义弹窗的页面有可能是可以滚动的,本来设计是弹窗出现后,蒙层后面的页面不能进行滚动的。实现方式是在蒙层的View中定义onTouchMove事件,并在事件处理方法中使用e.stopPropagation();阻止事件冒泡。但是经过测试,h5不存在问题,但是微信小程序中,滑动事件仍会向父组件传递了。原来写原生小程序时,可以用catchtouchmove处理的,但是Taro框架又不能使用catchtouchmove。

复现步骤
https://github.com/ItxiaoDz/taro-demo
master的最新一次提交可以复现这个问题。
image
“打开底层页面可以滚动的蒙层”这个按钮是复现我描述的问题的。
“打开能阻止底层页面滚动的蒙层”这个按钮我是强行使用了catchtouchmove,看最后编译出来的效果,后面的处理函数框架实际是没有将它当一个方法处理的,所以执行是会有警告:
image

// 应该在这里阻止滑动穿透的
disMove = (e: ITouchEvent) => {
    e.preventDefault();
    e.stopPropagation();
    return;
  }
// 复现问题的蒙层组件
      <View className={maskClassNames} onTouchMove={e => this.disMove(e)} onClick={this.closeScrollMask}>

      </View>

// 能阻止滑动穿透的蒙层组件,tsLint会报错:没有catchtouchmove这个属性
<View className={maskClassNames} catchtouchmove={e => this.disMove(e)} onClick={this.closeNotScrollMask}>

      </View>

期望行为
我觉得可以有3中处理方式:

  1. 能提供catchtouchmove的属性;
  2. 编译时,能将处理方法中含有e.stopPropagation()的事件编译成catchxxxx;
  3. Taro-ui的Curtain 幕帘组件能阻止滚动穿透。(这个的话只是能满足我当前具体的需求)

报错信息

系统信息

  • 操作系统: macOS 10.14.2
  • Taro 版本 Taro v1.3.9
  • Node.js 版本 10.15.3
  • 报错平台 weapp

补充信息

欢迎提交 Issue~

如果你提交的是 bug 报告,请务必遵循 Issue 模板的规范,尽量用简洁的语言描述你的问题,最好能提供一个稳定简单的复现。🙏🙏🙏

如果你的信息提供过于模糊或不足,或者已经其他 issue 已经存在相关内容,你的 issue 有可能会被关闭。

Good luck and happy coding~

@ItxiaoDz 我做过类似的操作

handleTouchMove = (e) => {
    e.preventDefault()
    e.stopPropagation()
  }

// jsx
<View className={classString} onTouchMove={this.handleTouchMove}>

我这里测试没问题的, iPhone8p

Hello~

您的问题楼上已经有了确切的回答,如果没有更多的问题这个 issue 将在 15 天后被自动关闭。

如果您在这 15 天中更新更多信息自动关闭的流程会自动取消,如有其他问题也可以发起新的 Issue。

Good luck and happy coding~

@IFmiss 嗯,确实这样写可以
我是使用了匿名函数的写法。。。这样就不能阻止事件冒泡了?
看来项目中onClick那些的重新测试一下才行

我写的是函数组件,还是不能阻止页面滚动

const handleTouchMove = (event: ITouchEvent) => {
    console.log(1)
    event.stopPropagation()
    event.preventDefault()
    return
  }

组织swiper左右滑动,但是不阻止上下页面滑动,请问这个要怎么处理呢

e.stopPropagation()doesn't work ?

https://nervjs.github.io/taro/docs/event.html#docsNav

    return (
      <View
        className='modal-overlay'
        onClick={this.closeModal}
        onScroll={(e) => this.stopScrollEvent(`scroll 1`, e)}
        onTouchStart={(e) => this.stopScrollEvent(`touch start 1`, e)}
        onTouchMove={(e) => this.stopScrollEvent(`touch move 1`, e)}
        onTouchEnd={(e) => this.stopScrollEvent(`touch end 1`, e)}
        onTouchCancel={(e) => this.stopScrollEvent(`touch cancel 1`, e)}
        onTap={(e) => this.stopScrollEvent(`tab 1`, e)}
        // catch
        onCatchScroll={(e) => this.stopScrollEvent(`catch scroll 1`, e)}
        onCatchTouchStart={(e) => this.stopScrollEvent(`catch touch start 1`, e)}
        onCatchTouchMove={(e) => this.stopScrollEvent(`catch touch move 1`, e)}
        onCatchTouchEnd={(e) => this.stopScrollEvent(`catch touch end 1`, e)}
        onCatchTouchCancel={(e) => this.stopScrollEvent(`catch touch cancel 1`, e)}
        onCatchTap={(e) => this.stopScrollEvent(`catch tab 1`, e)}
      >
        modal content
      </View>
    )

麻烦问一哈, 可以动态控制这个阻止滑动吗

这个问题依然存在,不能阻止整个页面page的滚动

麻烦问一哈, 可以动态控制这个阻止滑动吗

根据问题5909中的回答,onTouchMove 应该被编译成小程序中 catchtouchmove 方法了,当前版本不可以动态控制。

一层View catchMove ,里面放个ScrollView

View catchMove 下的 ScrollView 无法滚动

试了一下,最外层view设置catchMove,下的ScrollView可以滚动,但是View设置overflow-y:scroll就不生效,这是啥原因