onTouchTap 使用 material-ui 对话框触发两次

onTouchTap firing twice with material-ui dialog

我们有一个使用 Material-ui 显示对话框的 React 项目ui。出于某种原因,当您单击触发对话框打开的按钮时,似乎会触发第二个触摸事件,这可能会触发对话框上的 link 或按钮。当您通过单击按钮关闭对话框时,会发生类似的问题。执行此操作时,对话框会关闭,但会在您单击的元素正后方的元素上触发另一个触摸事件。

我们包含了 react-tap-event-plugin 以便使用 Material-ui 并且只要没有 2 个元素在此幽灵点击行为上重叠,该应用程序就可以正常运行.

这是我们组件的简化版本:

import React, { Component } from 'react'
import Dialog from 'material-ui/Dialog'

class Introduction extends Component {
  constructor(props) {
    super(props)

    this.state = { complete: false }

    this.finish = this.finish.bind(this)
  }

  finish() {
    this.setState({ complete: true })
  }

  render() {
    const actions = (
      <div>
        <button onTouchTap={this.finish}>Finish</button>
      </div>
    )

    if (!this.state.complete) {
      return (
        <Dialog open actions={actions}>
          <h3>Dialog header</h3>
          <p>Dialog text</p>
        </Dialog>
      )
    }

    return null
  }
}

当单击操作按钮 "Finish" 时,对话框关闭,然后它后面的元素也接收到 touchTap 事件。

如果有所不同,我们将使用 Cordova 来包装移动应用程序。我们仅在移动设备上遇到此问题(肯定是在 iOS 上),但在 Chrome.

中测试时在设备模式下也会遇到此问题

我做错了什么?如有任何建议,我们将不胜感激。

当我 运行 你的代码时,我得到这个错误:

Uncaught TypeError: Cannot read property 'setState' of null

所以这个关键字是空的。您需要将函数绑定到 class 实例。在构造函数中使用:

constructor(props) {
  super(props)
  this.finish = this.finish.bind(this);
  this.state = { complete: false }
}

或者

<button onTouchTap={this.finish.bind(this}>Finish</button>

或者您可以使用自动绑定到 class 的 es6 箭头函数。

finish = () => {
  this.setState({ complete: true })
}

我想当您尝试使用按钮打开它时也会出现同样的问题。

问题是延迟后触发onClick事件,不管你是否处理onTouchTap事件。因此,在触发 onTouchTap 事件并且您的 Dialog 关闭后,在您的 onTouchTap 事件被触发的同一位置延迟后会出现另一个 onClick 事件。因此,无论元素位于 'under' 你的 'touch' 对话框消失后,都会收到 onClick 事件。

解决此问题:在 onTouchTap 事件处理程序中调用 e.preventDefault()。 像这样:

<Button onTouchTap={(e) => { e.preventDefault(); this.finish()}}>Finish</Button>

希望对您有所帮助。