使用了antd-mobile的Picker造成点击事件多次触发

使用了antd-mobile的Picker造成点击事件多次触发

需求

页面上一个显示温度的div(<div className="tem">下称 .tem),点击时弹框,通过弹框修改这个温度的数据。

环境

使用 react hooks + antd-mobile,弹框使用 Picker 组件

实现

显示温度的div如下,其中的子组件<TemPicker >封装了Picker组件。当 .tem 被点击时,手动通过触发这个隐藏的 .itemForPicker 的点击事件来实现弹出。

……
const temPickerBar = useRef(null)
// 显示温度的点击事件
const temPickerClick = ({ target }) => {
    console.log('~~点击温度了', target)
    if (temPickerBar.current) {
        temPickerBar.current.click()
    }
}
……
// 显示温度的div
<div className='tem' onClick={temPickerClick}>
    <div className='value'>{temPickerVal}</div>
    <div className='text'>设定温度<i className='iconfont i-arrow_right' /></div>
    {currMode?.tem && temPickerVal && 
        <TemPicker tem={currMode.tem[0]} setTemVal={setTemVal} value={[temPickerVal]} pickerBar={temPickerBar} />
    }
</div>

// 子组件的jsx结构
<Picker data={[data]} value={[Number(value)]} onChange={v => setTemVal(v[0])} >
    <div className='itemForPicker' ref={pickerBar} style={{ display: pickerBar ? 'none' : 'flex' }}>
        <span className='content'>烹饪温度</span>
        <span className='extra'>{value + '℃'}</span>
        <i className='iconfont i-arrow_right' />
    </div>
</Picker>

问题

点击一次元素 .tem 时,框是弹出来了,也能隐藏。操作看起来一切正常,但通过打印发现点击事件共执行了4次,其中点击元素.time的瞬间触发2次,然后隐藏弹框时又触发2次,而我只需要点开时触发一次。

解决

  1. 查得每点击一次会触发2次事件的原因是item元素冒泡导致,在Picker的子元素上添加阻止冒泡事件即可解决,每次点击就会只触发一次。
  2. 每次隐藏弹框时自动触发的点击事件来源不明,又没找到阻断事件传播源的方法,最后的解决方案是:在点击事件传进来时,通过判断事件的目标元素中不包含 .tem 或其子元素来确认点击事件是被动触发的,从而阻止。
if (![target?.className, target?.parentElement?.className].includes('tem')) return

点击事件的完整代码:

const temPickerClick = ({ target }) => {
    // 由于弹窗关闭时会自动触发到这里来,造成不必要的点击事件,所以判断一下,如果不是手动点击的事件就屏蔽掉。
    if (![target?.className, target?.parentElement?.className].includes('tem')) return
    console.log('~~点击温度了', target)
    if (temPickerBar.current) {
        temPickerBar.current.click()
    }
}

注意:第二个解决方法已经覆盖了第一种,所以无需两种都写。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值