[英]How to use same event handler for click and touchend events but only run one of them?
Here is my code for overlay controls I'm working on https://repl.it/repls/AdoredMundaneFinance#index.js .这是我正在使用https://repl.it/repls/AdoredMundaneFinance#index.js的叠加控件的代码。 you can try interacting with it to see what functionality it offers.
您可以尝试与之交互以查看其提供的功能。
I've come across an issue where on touch devices, event for touchend and click both are fired.我遇到了一个问题,即在触摸设备上触发touchend的事件和click都被触发了。 Now Ive googled a lot,
现在我已经用谷歌搜索了很多,
a.一种。 I don't want to throttle due to user experience reasons.
由于用户体验原因,我不想节制。 Tried and didn't like it.
尝试过,不喜欢它。
b. b。 Tried event.preventDefault() , it ensures only one event is used BUT it stops event from reaching the target children, ie child divs which are supposed to receive these clicks/taps, so can't use this.
尝试过event.preventDefault() ,它确保仅使用一个事件,但会阻止事件到达目标子级,即应该接收这些点击/轻击的子级div,因此不能使用它。
c. C。 I tried event.stopPropogation() but that is causing other issues, I even tried calling it only when event is cancelable, you can try and see what I'm trying to say.
我尝试了event.stopPropogation(),但这引起了其他问题,我什至尝试仅在事件可取消时才调用它,您可以尝试看看我要说的是什么。
d. d。 I'm now trying to detect if the device is touch and based on that assign functions, but again I don't want to extend my problem to touch detection as well, as there is no "true" detection method, I don't want to risk that.
我现在正在尝试检测设备是否为触摸设备并基于该分配功能,但是我也不想将问题也扩展到触摸检测,因为没有“真正的”检测方法,我不会想要冒险。 What if someone is using mouse on touch device and click was being fired?
如果有人在触摸设备上使用鼠标并且触发了点击该怎么办? etc etc.
等等等
Please Help.请帮忙。
react:反应:
class App extends React.Component {
constructor() {
super();
this.hideAfterXTimeout = null;
this.state = {
visible: false
};
}
overlayRef(ref) {
if (!this.overlay) {
this.overlay = ref;
this.overlay.addEventListener("click", this.clickTouchEffect.bind(this));
this.overlay.addEventListener(
"touchend",
this.clickTouchEffect.bind(this)
);
let throttledHandler = this.throttle(300, this.mouseMoveEffect.bind(this));
this.overlay.addEventListener(
"mousemove",
throttledHandler.bind(this)
);
}
}
mouseMoveEffect(event) {
console.dir("called");
this.showControls();
}
clickTouchEffect(event) {
if (!event.target.hasAttribute("data-video")) {
if (this.state.visible) {
this.hideControls();
} else {
this.showControls();
}
} else {
this.showControls();
}
}
throttle(delay, fn) {
let lastCall = 0;
return function (...args) {
const now = (new Date).getTime();
if (now - lastCall < delay) {
return;
}
lastCall = now;
return fn(...args);
}
}
showControls() {
if(this.state.visible !== true){
this.setState({
visible: true
});
}
if (this.hideAfterXTimeout) {
clearTimeout(this.hideAfterXTimeout);
this.hideAfterXTimeout = null;
}
let _me = this;
this.hideAfterXTimeout = setTimeout(() => {
_me.hideControls();
}, 5000);
this.overlay.classList.remove("hide");
}
hideControls() {
this.setState({
visible: false
});
if (this.hideAfterXTimeout) {
clearTimeout(this.hideAfterXTimeout);
this.hideAfterXTimeout = null;
}
this.overlay.classList.add("hide");
}
cc(){
console.log("clicked");
}
render() {
return (
<div ref={this.overlayRef.bind(this)} className="overlay hide">
<div className="visibility">
<div onClick={this.cc.bind(this)} data-video="control" className="controls">
CC
</div>
</div>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('app'));
css: CSS:
.App {
font-family: sans-serif;
text-align: center;
}
.overlay {
width: 720px;
height: 405px;
outline: 1px solid red;
opacity: 1;
visibility: visible;
transition: 0.3s ease-out opacity;
}
.overlay.hide {
opacity: 0;
}
.overlay.hide > .visibility {
visibility: hidden;
}
.overlay > .visibility {
visibility: visible;
}
.controls {
width: 64px;
height: 64px;
outline: 1px solid blue;
Here is my code for overlay controls I'm working on https://repl.it/repls/AdoredMundaneFinance#index.js .这是我正在使用https://repl.it/repls/AdoredMundaneFinance#index.js的叠加控件的代码。 you can try interacting with it to see what functionality it offers.
您可以尝试与之交互以查看其提供的功能。
I've come across an issue where on touch devices, event for touchend and click both are fired.我遇到了一个问题,即在触摸设备上触发touchend的事件和click都被触发了。 Now Ive googled a lot,
现在我已经用谷歌搜索了很多,
a.一种。 I don't want to throttle due to user experience reasons.
由于用户体验原因,我不想节制。 Tried and didn't like it.
尝试过,不喜欢它。
b. b。 Tried event.preventDefault() , it ensures only one event is used BUT it stops event from reaching the target children, ie child divs which are supposed to receive these clicks/taps, so can't use this.
尝试过event.preventDefault() ,它确保仅使用一个事件,但会阻止事件到达目标子级,即应该接收这些点击/轻击的子级div,因此不能使用它。
c. C。 I tried event.stopPropogation() but that is causing other issues, I even tried calling it only when event is cancelable, you can try and see what I'm trying to say.
我尝试了event.stopPropogation(),但这引起了其他问题,我什至尝试仅在事件可取消时才调用它,您可以尝试看看我要说的是什么。
d. d。 I'm now trying to detect if the device is touch and based on that assign functions, but again I don't want to extend my problem to touch detection as well, as there is no "true" detection method, I don't want to risk that.
我现在正在尝试检测设备是否为触摸设备并基于该分配功能,但是我也不想将问题也扩展到触摸检测,因为没有“真正的”检测方法,我不会想要冒险。 What if someone is using mouse on touch device and click was being fired?
如果有人在触摸设备上使用鼠标并且触发了点击该怎么办? etc etc.
等等等
Please Help.请帮忙。
react:反应:
class App extends React.Component {
constructor() {
super();
this.hideAfterXTimeout = null;
this.state = {
visible: false
};
}
overlayRef(ref) {
if (!this.overlay) {
this.overlay = ref;
this.overlay.addEventListener("click", this.clickTouchEffect.bind(this));
this.overlay.addEventListener(
"touchend",
this.clickTouchEffect.bind(this)
);
let throttledHandler = this.throttle(300, this.mouseMoveEffect.bind(this));
this.overlay.addEventListener(
"mousemove",
throttledHandler.bind(this)
);
}
}
mouseMoveEffect(event) {
console.dir("called");
this.showControls();
}
clickTouchEffect(event) {
if (!event.target.hasAttribute("data-video")) {
if (this.state.visible) {
this.hideControls();
} else {
this.showControls();
}
} else {
this.showControls();
}
}
throttle(delay, fn) {
let lastCall = 0;
return function (...args) {
const now = (new Date).getTime();
if (now - lastCall < delay) {
return;
}
lastCall = now;
return fn(...args);
}
}
showControls() {
if(this.state.visible !== true){
this.setState({
visible: true
});
}
if (this.hideAfterXTimeout) {
clearTimeout(this.hideAfterXTimeout);
this.hideAfterXTimeout = null;
}
let _me = this;
this.hideAfterXTimeout = setTimeout(() => {
_me.hideControls();
}, 5000);
this.overlay.classList.remove("hide");
}
hideControls() {
this.setState({
visible: false
});
if (this.hideAfterXTimeout) {
clearTimeout(this.hideAfterXTimeout);
this.hideAfterXTimeout = null;
}
this.overlay.classList.add("hide");
}
cc(){
console.log("clicked");
}
render() {
return (
<div ref={this.overlayRef.bind(this)} className="overlay hide">
<div className="visibility">
<div onClick={this.cc.bind(this)} data-video="control" className="controls">
CC
</div>
</div>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('app'));
css: CSS:
.App {
font-family: sans-serif;
text-align: center;
}
.overlay {
width: 720px;
height: 405px;
outline: 1px solid red;
opacity: 1;
visibility: visible;
transition: 0.3s ease-out opacity;
}
.overlay.hide {
opacity: 0;
}
.overlay.hide > .visibility {
visibility: hidden;
}
.overlay > .visibility {
visibility: visible;
}
.controls {
width: 64px;
height: 64px;
outline: 1px solid blue;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.