右键点击事件:
世上本没问题,闲多了,就有了问题: 开会不准玩电脑,只能玩手机,玩儿了阵子扫雷,决定自己做一个网页版。三下五除二做完之后,猛然发现,手机没有右键。。。。。。没有右键怎么插小红旗?!
想起来app上是用长按来插小红旗的,于是开始了长达几个小时的纠结。
React Component监听点击事件
最开始的时候,格子接受左键和右键点击不同的event。
onClick
用来监听左键点击,onContextMenu
用来监听右键点击,可以愉快的玩耍,么得问题的。
import React from 'react';
import '../styles/grid.css'
class SingleGrid extends React.Component {
constructor(props) {
super(props);
this.state = {status: 'default'};
this.handleClick = this.handleClick.bind(this);
this.handleRightClick = this.handleRightClick.bind(this);
}
handleClick() {
//....一些左键点击事件处理逻辑,与本文无关。。。。
}
handleRightClick(e) {
//此处省略若干行
// marked是插小红旗,default是啥都没有,
this.setState({
status: this.state.status === 'marked' ? 'default' : 'marked'
});
}
render () {
let currentStatue = '';
//。。。此处省略若干行。。。
return <span
className={`grid${currentStatue} grid ${currentStatue && currentStatue!== 'marked' ? 'open' : 'default' }`}
onClick={this.handleClick}
onContextMenu={this.handleRightClick}
>{/*格子内容省略*/}</span>
}
}
export default SingleGrid
手机用长按代替右键点击
直到,开会不准玩电脑呀!手机怎么搞啊?祭出longPress大法:网上找了好几个react的lib,都不老好用,不是install时出问题就是build时出问题(时间主要浪费在这里了)。放弃lib,自己搞。
网上代码很多,大概是按住之后setTimeout,松开之后cancel timeout。
/**
* Created by xzou2 on 11/13/18.
*/
import React from 'react';
import '../styles/grid.css'
class SingleGrid extends React.Component {
constructor(props) {
super(props);
this.state = {status: 'default'};
this.handleClick = this.handleClick.bind(this);
this.handleRightClick = this.handleRightClick.bind(this);
this.handleTouchEnd = this.handleTouchEnd.bind(this);
this.touchStart = this.touchStart.bind(this);
}
handleClick() {
//一直是个不惹麻烦的乖宝宝
}
handleRightClick(e) {
//同上
}
handleTouchEnd(){
clearTimeout(this.pressTime);
}
touchStart(){
this.pressTime = setTimeout(()=>{
this.setState({
status: this.state.status === 'marked' ? 'default' : 'marked'
});
}, '1000');
}
render () {
let currentStatue = '';
//此处省略乖宝宝代码
return <span
className={`grid${currentStatue} grid ${currentStatue && currentStatue!== 'marked' ? 'open' : 'default' }`}
onClick={this.handleClick}
onContextMenu={this.handleRightClick}
onTouchStart={this.touchStart}
onTouchEnd={this.handleTouchEnd}
>{/*格子内容省略*/}</span>
}
}
export default SingleGrid
onTouchStart和onContextMenu重复执行
问题出现了,长按之后,小红旗插上了,但是只要稍微松开晚一些,小红旗就又取消了。
经过观察,按住之后超过一段时间,render()
方法执行了两遍。经过漫长的debug,原来handleRightClick
方法也被执行了。负负得正,一个插旗一个拔旗。
花了一些时间研究了一下为啥浏览器会trigger 右键点击事件,未果,一拍脑门,既然不能阻止浏览器触发事件,那就让他触发,但是不干活就是了。所以handleRightClick
方法在touchStart被触发的时候(触屏)就不要干活了。
handleRightClick(e) {
e.stopPropagation();//这两行是为了阻止出现浏览器菜单
e.preventDefault();
if(this.pressTime) {return;} //如果touchstart触发,说明是触屏,这个方法不往下执行。
this.setState({
status: this.state.status === 'marked' ? 'default' : 'marked'
});
}
到目前为止,大概,可能。。。已经解决了这个事儿了吧,如果又有新的bug,再说吧。