What you can do is use a flag indicating that you were in the touch event before being in the mouse event if you are using the bubble phase . Therefore, attach a listener to your container element as follows:
let isTouch = false; const handleContainerClick = () => isTouch = false; const handleMuteClick = () => { if (isTouch == false) { console.log("mute toggled"); } }; const volumeControlOnClick = () => { isTouch = true; }; class Volume extends React.Component { constructor(props) { super(props); this.state = {}; } render() { return ( <div className="jp-volume-container" onClick={handleContainerClick}> <Mute onTouchStart={volumeControlOnClick} onClick={handleMuteClick}><i className="fa fa-volume-up" /></Mute> <div className="jp-volume-controls"> <div className="jp-volume-bar-container"> <VolumeBar /> </div> </div> </div> ); } }; class Mute extends React.Component { render() { return ( <button className="jp-mute" onTouchStart={this.props.onTouchStart} onClick={this.props.onClick}> {this.props.children} </button> ); } }; class VolumeBar extends React.Component { render() { return ( <div className="jp-volume-bar" onClick={() => console.log("bar moved")}> {this.props.children} </div> ); } }; render(<Volume />, document.getElementById('container'));
If you are not using the bubble phase, so that you can register a timeout of 100 ms with the same logic above, where after 100 ms again make your flag variable false. Just add a touchStart handler:
setTimeout(() => {isTouch = false}, 100);
EDIT: Although touch events must be passive by default in Chrome 56, you call preventDefault () from the touchEnd event to prevent click firing. So, if you cannot modify the click handler of your Mute class in any way, but you can add a touchEnd event than you could:
const handleTouchEnd = (e) => e.preventDefault(); const volumeControlOnClick = () => console.log("volumeControlOnClick"); class Volume extends React.Component { constructor(props) { super(props); this.state = {}; } render() { return ( <div className="jp-volume-container"> <Mute onTouchStart={volumeControlOnClick} onTouchEnd={handleTouchEnd}><i className="fa fa-volume-up" /></Mute> <div className="jp-volume-controls"> <div className="jp-volume-bar-container"> <VolumeBar /> </div> </div> </div> ); } }; class Mute extends React.Component { render() { return ( <button className="jp-mute" onTouchStart={this.props.onTouchStart} onTouchEnd={this.props.onTouchEnd} onClick={() => console.log("mute toggled")}> {this.props.children} </button> ); } }; class VolumeBar extends React.Component { render() { return ( <div className="jp-volume-bar" onClick={() => console.log("bar moved")}> {this.props.children} </div> ); } }; render(<Volume />, document.getElementById('container'));
source share