一、场景
- 在项目当中,基础遇到这样的需求
有一个长列表,或者其他可滚动展示的页面,
在这个页面会弹出一个Modal层,如下:
贝壳找房的 的筛选栏

二、问题
如果这个弹框内容不可滚动,不会有太大问题;
但是当弹出内容是可以滚动的时候,就会有问题,
触摸没有滚动的区域会发现滚动可以穿透,会传递给下面的列表页面,
三、解决方案
思路解析
i、首先,需要在自定义弹框的根元素,添加 onTouchMove 监听,并阻止时间的冒泡
// 重点A:阻止事件冒泡handleTouchMove = (e) => {e.stopPropagation()}<View className='rootClass' onTouchMove={this.handleTouchMove}>
ii、但是,里面的内容,就不能滚动了,那么,可以使用 ScrollView代替View,并开启Y轴的滚动
<!-- 重点B: ScrollView(开启scrollY)--><ScrollViewscrollYscrollX={false}className='layout-body__content'><!-- 内容区域--><!-- 内容区域--></ScrollView>
完整代码
// 重点A:阻止事件冒泡handleTouchMove = (e) => {e.stopPropagation()}render() {return (<View className='rootClass' onTouchMove={this.handleTouchMove}><!-- 遮罩层 --><View onClick={this.close} /><!-- 重点B: ScrollView(开启scrollY)--><ScrollViewscrollYscrollX={false}className='layout-body__content'><!-- 内容区域--><!-- 内容区域-->{this.props.children}</ScrollView></View>)}
最终效果

四、关于stopPropagation
简单来说:
JS中,冒泡和捕获是事件流的两种行为,
使用event.stopPropagation()可以起到阻止捕获和冒泡阶段中当前事件的进一步传播。
而使用event.preventDefault()可以取消默认事件。
事件流
事件流描述的是从页面中接受事件的顺序,分为
- IE的事件流是 事件冒泡流,
- 标准的浏览器事件流是 事件捕获流。
