一、场景
- 在项目当中,基础遇到这样的需求
有一个长列表,或者其他可滚动展示的页面,
在这个页面会弹出一个Modal
层,如下:
贝壳找房的 的筛选栏
二、问题
如果这个弹框内容不可滚动,不会有太大问题;
但是当弹出内容是可以滚动的时候,就会有问题,
触摸没有滚动的区域会发现滚动可以穿透,会传递给下面的列表页面,
三、解决方案
思路解析
i、首先,需要在自定义弹框的根元素,添加 onTouchMove
监听,并阻止时间的冒泡
// 重点A:阻止事件冒泡
handleTouchMove = (e) => {
e.stopPropagation()
}
<View className='rootClass' onTouchMove={this.handleTouchMove}>
ii、但是,里面的内容,就不能滚动了,那么,可以使用 ScrollView
代替View
,并开启Y轴的滚动
<!-- 重点B: ScrollView(开启scrollY)-->
<ScrollView
scrollY
scrollX={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)-->
<ScrollView
scrollY
scrollX={false}
className='layout-body__content'
>
<!-- 内容区域-->
<!-- 内容区域-->
{this.props.children}
</ScrollView>
</View>
)
}
最终效果
四、关于stopPropagation
简单来说:
JS中,冒泡和捕获是事件流的两种行为,
使用event.stopPropagation()
可以起到阻止捕获和冒泡阶段中当前事件的进一步传播。
而使用event.preventDefault()
可以取消默认事件。
事件流
事件流描述的是从页面中接受事件的顺序,分为
- IE的事件流是 事件冒泡流,
- 标准的浏览器事件流是 事件捕获流。