admin管理员组文章数量:1387339
I have the following rather simple React Class:
import React from "react"
export default class DoubleClick extends React.Component {
constructor(props) {
super(props);
this.state = {
};
this.handleClick = this.handleClick.bind(this);
this.handleDoubleClick = this.handleDoubleClick.bind(this);
}
handleClick() {
console.log("Click");
}
handleDoubleClick() {
console.log("Double Click");
}
render() {
return (
<div style={{backgroundColor: 'pink'}}>
<div onClick={this.handleClick}>
<span onDoubleClick={this.handleDoubleClick}> Hello </span>
<span onDoubleClick={this.handleDoubleClick}> world. </span>
</div>
</div>
);
}
}
When somebody single-clicks on the outer div, I want to call handleClick
, when somebody double-clicks on any of the inner spans I want to call handleDoubleClick
, but not the handleClick
for the outer div as well.
However, whenever I double-click, handleDoubleClick()
is called, but handleClick
is also called, namely twice.
I would like to call handleClick()
only when I click, but do not double-click - is this possible?
I have the following rather simple React Class:
import React from "react"
export default class DoubleClick extends React.Component {
constructor(props) {
super(props);
this.state = {
};
this.handleClick = this.handleClick.bind(this);
this.handleDoubleClick = this.handleDoubleClick.bind(this);
}
handleClick() {
console.log("Click");
}
handleDoubleClick() {
console.log("Double Click");
}
render() {
return (
<div style={{backgroundColor: 'pink'}}>
<div onClick={this.handleClick}>
<span onDoubleClick={this.handleDoubleClick}> Hello </span>
<span onDoubleClick={this.handleDoubleClick}> world. </span>
</div>
</div>
);
}
}
When somebody single-clicks on the outer div, I want to call handleClick
, when somebody double-clicks on any of the inner spans I want to call handleDoubleClick
, but not the handleClick
for the outer div as well.
However, whenever I double-click, handleDoubleClick()
is called, but handleClick
is also called, namely twice.
I would like to call handleClick()
only when I click, but do not double-click - is this possible?
- Possible duplicate of onClick works but onDoubleClick is ignored on React ponent – Dez Commented Feb 16, 2018 at 20:16
- It's not ignored in my case though. – R. Kohlisch Commented Feb 16, 2018 at 20:17
- But the accepted answer is what you need to know. Not being able to differentiate single from double click in the same DOM ponent is a DOM limitation: stackoverflow./a/25780754/305953 – Dez Commented Feb 16, 2018 at 20:18
- So it's just not possible to differentiate the two? – R. Kohlisch Commented Feb 16, 2018 at 20:20
- It is not possible to do reliably. It is possible to implement heuristics to e close with some important limitations such as sacrificing accessibility. As such it wouldn't be advisable, instead try to rearrange your elements so their events don't clash. – Nic Nilov Commented Feb 16, 2018 at 20:28
2 Answers
Reset to default 5I have a HOC that I use to approximate what you're looking for:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
export default class DoubleClick extends Component {
constructor(props) {
super(props);
this.onClick = this.onClick.bind(this);
this.onDoubleClick = this.onDoubleClick.bind(this);
this.timeout = null;
}
onClick(e) {
e.preventDefault();
if(this.timeout === null) {
this.timeout = window.setTimeout(() => {
this.timeout = null;
this.props.onClick();
}, 300);
}
}
onDoubleClick(e) {
e.preventDefault();
window.clearTimeout(this.timeout);
this.timeout = null;
this.props.onDoubleClick();
}
render() {
const { onClick, onDoubleClick, children, ...childProps } = this.props;
const props = Object.assign(childProps, { onClick: this.onClick, onDoubleClick: this.onDoubleClick });
return React.cloneElement(children, props);
}
}
DoubleClick.propTypes = {
onClick: PropTypes.func.isRequired,
onDoubleClick: PropTypes.func.isRequired,
children: PropTypes.element.isRequired,
};
Used like this:
<DoubleClick onClick={clickHandler} onDoubleClick={doubleClickHandler}>
<button>Click or double click me</button>
</DoubleClick>
When the first click is received, it sets a 300ms timeout. If no second click is received within 300ms, the function in the onClick
prop will be invoked. If a second click is received within 300ms, the function in the onDoubleClick
prop will be invoked, and the timeout is canceled so the onClick
does not fire.
Needless to say, this is an imperfect approximation, but I've found it to be a sufficiently satisfying user experience in practice.
Like others said, it's not possible to do a click event on the parent with a doubleClick on the children without a timeout (I think).
If you can sacrifice the UX part of the 500ms until the click is recognized as a non-doubleclick you can work with timeout.
constructor(props) {
super(props);
this.state = {
};
this.handleClick = this.handleClick.bind(this);
this.handleDoubleClick = this.handleDoubleClick.bind(this);
// hack doubleclick
this.doubleClickTimeout = 500; // default doubleclick timeout
this.clickedTimeout = null;
}
handleClick(ev) {
if (!this.clickedTimeout) {
this.clickedTimeout = setTimeout(() => {
this.clickedTimeout = null;
// do your stuff here
console.log('Clicked');
}, this.doubleClickTimeout);
}
}
handleDoubleClick() {
clearTimeout(this.clickedTimeout);
this.clickedTimeout = null;
console.log("Double Click");
}
render() {
return (
<div style={{backgroundColor: 'pink'}}>
<div onClick={this.handleClick}>
<span onDoubleClick={this.handleDoubleClick}> Hello </span>
<span onDoubleClick={this.handleDoubleClick}> world. </span>
</div>
</div>
);
}
本文标签: javascriptPrevent a doubleclick being interpreted as two singleclicksStack Overflow
版权声明:本文标题:javascript - Prevent a double-click being interpreted as two single-clicks? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744518341a2610300.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论