Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

onTouchTap firing twice with material-ui dialog

We have built a React project that is using Material-ui to show dialog boxes. For some reason, when you click a button which triggers the dialog to open, a second touch event seems to fire which will potentially trigger a link or button that is on the dialog box. A similar issue happens when you close the dialog box by clicking on a button. When doing this, the dialog closes, but will trigger another touch event on an element that is directly behind the element you clicked on.

We have included the react-tap-event-plugin in order to use Material-ui and the app works really well as long as there aren't 2 elements overlapping on this ghost tap behaviour.

This is a simplified version of what our component looks like:

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
  }
}

It's when that action button "Finish" is clicked that the dialog closes and then an element behind it also receives a touchTap event.

If it makes a difference, we are using Cordova to wrap the app for mobile. We are experiencing this issue only on mobile (definitely on iOS), but also on device mode while testing in Chrome.

What am I doing wrong? Any advice would be appreciated.

like image 347
Blair Avatar asked Jul 14 '16 00:07

Blair


1 Answers

The problem is that after a delay an onClick event is triggered, whether you handle the onTouchTap event or not. So after the onTouchTap event is triggered and your Dialog closes there comes another onClick event after a delay at the same location your onTouchTap event was fired on. So whatever element lies 'under' your 'touch' after the dialog is gone will receive the onClick event.

To Fix this: call e.preventDefault() inside the onTouchTap event handler. Like this:

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

Hope this helps.

like image 86
JamesAlias Avatar answered Oct 29 '22 18:10

JamesAlias