Search code examples
reactjstouchontouch

DOM changes stop touch event listeners


I have an issue with React touch events handlings that stop working when the DOM changes. I have a parent item with a onTouchMove handler. If I start my touch movement above this element and a child element that disappears during the touch movement my handler stops being called.

I reproduced there: https://codepen.io/anon/pen/pmRvmB?editors=0110#0

(To test touch events you need to use the responsive design mode and enable touch events in Chrome or Firefox) The parent div (the green) has the onTouchMove handler, everything works fine if you start the touch outside of the blue child div, but if you start it in the blue div, when this one disappears (when your cursor x goes above a certain threshold in the code) the touch handler stops being called.

Here is the corresponding JS code reproducing this issue:

class TodoApp extends React.Component {
  constructor(props) {
    super(props);
    this.onTouchMove = this.onTouchMove.bind(this);
    this.state = {
      touchCurrentX: 0
    }
  }

  onTouchMove(ev) {
        console.log('onTouchMove');
        const x = ev.touches.item(0).screenX;
            this.setState({touchCurrentX: x});
  }

  render() {
    const child = this.state.touchCurrentX < 600 ? React.createElement('div', {key: 0, id: 'child'}, []) : null;
    const debug = React.createElement('span', {key: 1}, this.state.touchCurrentX);
    return React.createElement('div', {id: 'parent', onTouchMove: this.onTouchMove}, [child, debug]);
  }
}

ReactDOM.render(React.createElement(TodoApp, {}, []), document.querySelector("#app"))

Is there a way to have my handler being still called even if children elements disappear?


Solution

  • The simplest way to achieve this is to let touch events fall through the children onto the parent. Simply add style: { pointerEvents: "none" } to child props or add it into your CSS. This is not a perfect solution, however. Some children may need their pointer events and IE may object to the CSS property.