反应水平滚动选项卡跳上水龙头?

时间:2020-06-19 23:35:03

标签: javascript reactjs

我有一个组件,可以在计算机上的Web浏览器上完美运行。您单击动物名称以在下面显示动物,或者单击并拖动以水平滚动以显示更多动物。

在诸如iPhone之类的触摸设备上进行测试时,您可以单击动物名称并起作用,但是一旦用手指水平滚动,则点击以选择动物,它会跳跃而不选择动物。

关键是要使代码在上面显示的两台计算机和触摸设备上都可以工作,而在那儿它会中断。

Here is the sandbox

有什么想法我们可以解决这个问题吗?

1 个答案:

答案 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在这里有什么用,所以我保持原样,但是您也可以删除它,它也将起作用

工作演示:(有超时)

Edit gracious-hill-i7ndz4

工作演示:(无超时)

Edit #SO-without-timeout