我有以下相当简单的React类:
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>
);
}
}
当有人单击外部div时,我想调用handleClick
,当有人双击我要调用handleDoubleClick
的任何内部空间时,而不是{{1}对于外部div也是如此。
但是,每当我双击时,handleClick
被调用,但 handleDoubleClick()
也会被调用,即两次。
我只想在点击时调用handleClick
,但不双击 - 这可能吗?
答案 0 :(得分:2)
我有一个HOC用于估算您正在寻找的内容:
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,
};
像这样使用:
<DoubleClick onClick={clickHandler} onDoubleClick={doubleClickHandler}>
<button>Click or double click me</button>
</DoubleClick>
收到第一次点击后,会设置300毫秒超时。如果在300毫秒内没有收到第二次点击,将调用onClick
道具中的函数。如果在300毫秒内收到第二次点击,将调用onDoubleClick
道具中的函数,并取消超时,以便onClick
不会触发。
毋庸置疑,这是一个不完美的近似,但我发现它在实践中是一种足够令人满意的用户体验。
答案 1 :(得分:0)
就像其他人所说的那样,不能在没有超时的情况下对孩子进行双击(我认为),对父母点击事件是不可能的。
如果您可以牺牲500毫秒的UX部分,直到点击被识别为非双击,您可以使用超时。
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>
);
}