我有一个组件,可以在计算机上的Web浏览器上完美运行。您单击动物名称以在下面显示动物,或者单击并拖动以水平滚动以显示更多动物。
在诸如iPhone之类的触摸设备上进行测试时,您可以单击动物名称并起作用,但是一旦用手指水平滚动,则点击以选择动物,它会跳跃而不选择动物。
关键是要使代码在上面显示的两台计算机和触摸设备上都可以工作,而在那儿它会中断。
有什么想法我们可以解决这个问题吗?
答案 0 :(得分:2)
问题:未正确使用setTimeout
您也可以在网络上生成问题,只需在任意元素上单击一次时间,它就会被选中并且可以拖动,但是应该选择它。那么为什么这种奇怪的行为。让我们看看
// execution flow, when you just single click and don't drag
onMouseDown = e => {
const tabsH = ReactDOM.findDOMNode(this.refs["tabsH"]); // <----------------- 1
setTimeout(() => { // <----------------- 2
// here we are adding active class ,
// that will not be removed, because (no 5) already executed before this
// which makes your element draggable
tabsH.classList.add("active"); // <----------------- 7
this.setState({ // <----------------- 7.1
isPressedDown: true,
startX: e.pageX - tabsH.offsetLeft,
scrollLeft: tabsH.scrollLeft
});
}, 100);
};
onMouseUp = () => {
const tabsH = ReactDOM.findDOMNode(this.refs["tabsH"]); // <----------------- 3
this.setState({ isPressedDown: false }); // <----------------- 4
tabsH.classList.remove("active"); // <----------------- 5
setTimeout(() => { // <----------------- 6
this.setState({ isScrolling: false }); // <----------------- 8
}, 500);
};
解决方案:
1)将4号和5号放在setTimeout
2)确保setTimeout
内的onMouseUp
时间大于onMouseDown
setTimeout
的时间(以解决单击问题)
onMouseDown = e => {
const tabsH = ReactDOM.findDOMNode(this.refs["tabsH"]);
setTimeout(() => {
tabsH.classList.add("active");
this.setState({
isPressedDown: true,
startX: e.pageX - tabsH.offsetLeft,
scrollLeft: tabsH.scrollLeft
});
}, 100);
};
onMouseUp = () => {
const tabsH = ReactDOM.findDOMNode(this.refs["tabsH"]);
setTimeout(() => {
tabsH.classList.remove("active"); // <---- this should be inside setTimout
this.setState({ isPressedDown: false }); // <---- this should be inside setTimout
this.setState({ isScrolling: false });
}, 200); // <---- just make sure that this is greater than the `onMouseDown` setTimeout
};
注意::我不知道
setTimeout
在这里有什么用,所以我保持原样,但是您也可以删除它,它也将起作用
工作演示:(有超时)
工作演示:(无超时)