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

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

需求

页面上一个显示温度的div(

下称 .tem),点击时弹框,通过弹框修改这个温度的数据。

环境

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

实现

显示温度的div如下,其中的子组件封装了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()
    }
}

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

你可能感兴趣的:(前端移动开发,前端,react,antd-mobile,picker,弹框,点击事件多次触发)