thi*_*bus 54 javascript reactjs
我正在使用React构建一个Minesweeper游戏,并希望在单击或双击单元格时执行不同的操作.目前,该onDoubleClick功能永远不会触发,显示警报onClick.如果我删除onClick处理程序,onDoubleClick工作.为什么两个事件都不起作用?是否可以在元素上同时包含两个事件?
/** @jsx React.DOM */
var Mine = React.createClass({
render: function(){
return (
<div className="mineBox" id={this.props.id} onDoubleClick={this.props.onDoubleClick} onClick={this.props.onClick}></div>
)
}
});
var MineRow = React.createClass({
render: function(){
var width = this.props.width,
row = [];
for (var i = 0; i < width; i++){
row.push(<Mine id={String(this.props.row + i)} boxClass={this.props.boxClass} onDoubleClick={this.props.onDoubleClick} onClick={this.props.onClick}/>)
}
return (
<div>{row}</div>
)
}
})
var MineSweeper = React.createClass({
handleDoubleClick: function(){
alert('Double Clicked');
},
handleClick: function(){
alert('Single Clicked');
},
render: function(){
var height = this.props.height,
table = [];
for (var i = 0; i < height; i++){
table.push(<MineRow width={this.props.width} row={String.fromCharCode(97 + i)} onDoubleClick={this.handleDoubleClick} onClick={this.handleClick}/>)
}
return (
<div>{table}</div>
)
}
})
var bombs = ['a0', 'b1', 'c2'];
React.renderComponent(<MineSweeper height={5} width={5} bombs={bombs}/>, document.getElementById('content'));
Run Code Online (Sandbox Code Playgroud)
Ros*_*len 51
这不是React的限制,它是DOM click和dblclick事件的限制.正如Quirksmode的点击文档所示:
不要在同一元素上注册click和dblclick事件:不可能将单击事件与导致dblclick事件的单击事件区分开来.
有关更新的文档,该dblclick事件的W3C规范指出:
当在元素上单击指针设备的主按钮两次时,用户代理必须调度此事件.
两次单击事件后必然会发生双击事件.
编辑:
另一个建议读取是jQuery的dblclick处理程序:
将处理程序绑定到同一元素的click和dblclick事件是不可取的.触发的事件序列因浏览器而异,有些事件在dblclick之前接收到两个点击事件,而其他事件只接收一个事件.双击敏感度(双击检测到的点击之间的最长时间)可能因操作系统和浏览器而异,通常可由用户配置.
Aka*_*edi 17
通过在触发正常点击动作时提供非常小的延迟可以实现所需的结果,当双击事件发生时将被取消.
let timer = 0;
let delay = 200;
let prevent = false;
doClickAction() {
console.log(' click');
}
doDoubleClickAction() {
console.log('Double Click')
}
handleClick() {
let me = this;
timer = setTimeout(function() {
if (!prevent) {
me.doClickAction();
}
prevent = false;
}, delay);
}
handleDoubleClick(){
clearTimeout(timer);
prevent = true;
this.doDoubleClickAction();
}
< button onClick={this.handleClick.bind(this)}
onDoubleClick = {this.handleDoubleClick.bind(this)} > click me </button>
Run Code Online (Sandbox Code Playgroud)
Erm*_*Nea 17
您可以使用自定义钩子来处理简单的单击和双击,如下所示:
import { useState, useEffect } from 'react';
function useSingleAndDoubleClick(actionSimpleClick, actionDoubleClick, delay = 250) {
const [click, setClick] = useState(0);
useEffect(() => {
const timer = setTimeout(() => {
// simple click
if (click === 1) actionSimpleClick();
setClick(0);
}, delay);
// the duration between this click and the previous one
// is less than the value of delay = double-click
if (click === 2) actionDoubleClick();
return () => clearTimeout(timer);
}, [click]);
return () => setClick(prev => prev + 1);
}
Run Code Online (Sandbox Code Playgroud)
然后在您的组件中,您可以使用:
const click = useSingleAndDoubleClick(callbackClick, callbackDoubleClick);
<button onClick={click}>clic</button>
Run Code Online (Sandbox Code Playgroud)
Jef*_*ley 13
编辑:
我发现这不是React 0.15.3的问题.
原版的:
对于React 0.13.3,这里有两个解决方案.
请注意,即使在双击的情况下,单击处理程序也会被调用两次(每次单击一次).
const ListItem = React.createClass({
handleClick() {
console.log('single click');
},
handleDoubleClick() {
console.log('double click');
},
refCallback(item) {
if (item) {
item.getDOMNode().ondblclick = this.handleDoubleClick;
}
},
render() {
return (
<div onClick={this.handleClick}
ref={this.refCallback}>
</div>
);
}
});
module.exports = ListItem;
Run Code Online (Sandbox Code Playgroud)
我有另一个使用的解决方案lodash,但由于复杂性我放弃了它.这样做的好处是"点击"只被调用一次,而在"双击"的情况下则完全没有.
import _ from 'lodash'
const ListItem = React.createClass({
handleClick(e) {
if (!this._delayedClick) {
this._delayedClick = _.debounce(this.doClick, 500);
}
if (this.clickedOnce) {
this._delayedClick.cancel();
this.clickedOnce = false;
console.log('double click');
} else {
this._delayedClick(e);
this.clickedOnce = true;
}
},
doClick(e) {
this.clickedOnce = undefined;
console.log('single click');
},
render() {
return (
<div onClick={this.handleClick}>
</div>
);
}
});
module.exports = ListItem;
Run Code Online (Sandbox Code Playgroud)
我很欣赏的想法,双击是不容易发现的东西,但是是好还是坏它IS存在用户理解,因为它在操作系统中流行的范式和一个.此外,它是现代浏览器仍然支持的范例.直到将它从DOM规范中删除为止,我认为React应该支持一个功能onDoubleClick正确的支柱onClick.不幸的是,他们似乎没有.
ondoubleclick您可以使用event.detail来获取当前点击次数,而不是使用。它是鼠标在短时间内在同一区域被点击的次数。
const handleClick = (e) => {
switch (e.detail) {
case 1:
console.log("click");
break;
case 2:
console.log("double click");
break;
case 3:
console.log("triple click");
break;
}
};
return <button onClick={handleClick}>Click me</button>;
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,如果您三次单击按钮,它将打印所有 3 个案例:
click
double click
triple click
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
51922 次 |
| 最近记录: |