首页 > 解决方案 > 反应水平滚动标签在点击时跳跃?

问题描述

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

在 iPhone 等触控设备上进行测试时,您可以单击动物名称,它可以工作,但是一旦您用手指水平滚动,然后点击选择动物,它会跳转并且不会选择动物。

关键是代码可以在如上所示的两台计算机和触摸设备上运行,这就是它中断的地方。

这里是沙盒

知道我们如何解决这个问题吗?

标签: javascriptreactjs

解决方案


问题:setTimeout正确使用

您也可以在 Web 上生成问题,您只需单击任何元素,它就会被选中并且可以拖动,但它应该只是选择。那么为什么会有这种奇怪的行为。让我们看看

// 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这里有什么用,所以我只是保持原样,但你也可以删除它,它也可以工作

工作演示:(超时)

编辑 gracious-hill-i7ndz4

工作演示:(没有超时)

编辑#SO-without-timeout


推荐阅读