【问题标题】:How to block the horizontal swipe function when scrolling vertically (on mobile phones)垂直滚动时如何阻止水平滑动功能(在手机上)
【发布时间】:2021-07-15 10:08:33
【问题描述】:

我有一个可以水平滑动对象的功能。垂直滚动页面时如何阻止水平滑动功能/事件。

我想出了如何阻止垂直滚动,但我找不到水平滚动的解决方案,也许有人遇到了类似的问题并且可以提出解决方案的算法,或者也许有人还有一些基础工作?

这是一个关于代码框的完整示例(仅适用于触摸事件)。

https://codesandbox.io/s/long-architecture-0k6rb?file=/src/scroll.js:2945-3250&resolutionWidth=1072&resolutionHeight=675

  let ref = useRef();

  const [state, setState] = useState({
    isScrolling: false,
    clientX: 0, 
    scrollX: 0 
  });

  const touchStartHandler = (e) => {
    if (ref && ref.current && !ref.current.contains(e.target)) {
      return;
    }
    e.preventDefault();
    setState({
      ...state,
      isScrolling: true,
      clientX: e.touches[0].clientX
    });
  };

  const touchMoveHandler = (e) => {
    if (ref && ref.current && !ref.current.contains(e.target)) {
      return;
    }
    e.preventDefault();

    const { clientX, scrollX, isScrolling } = state;

    if (isScrolling === true) {
      let sX = scrollX - e.touches[0].clientX + clientX;
      let cX = e.touches[0].clientX;

      if (sX < -0) {
        sX = 0;
      } else if (sX >= 0 && sX <= 1800) {
        ref.current.scrollLeft = sX;
      }
      setState({
        ...state,
        scrollX: sX,
        clientX: cX
      });
    }
  };

  const touchEndHandler = (e) => {
    if (ref && ref.current && !ref.current.contains(e.target)) {
      return;
    }
    e.preventDefault();
    setState({
      ...state,
      isScrolling: false
    });
  };
  
    useEffect(() => {
    document.addEventListener("touchstart", touchStartHandler);
    document.addEventListener("touchmove", touchMoveHandler);
    document.addEventListener("touchend", touchEndHandler);
    return () => {                                               document.removeEventListener("touchstart", touchStartHandler);                  
      document.removeEventListener("touchmove", touchMoveHandler);
      document.removeEventListener("touchend", touchEndHandler);
    };
  });
  
    return (
    <div className={classes.charPage}>
      <div
        className={classes.items}
        ref={ref}
        onTouchStart={touchStartHandler}
        onTouchMove={touchMoveHandler}
        onTouchEnd={touchEndHandler}
      >
        {scrollBar}
      </div>
    </div>
  );

【问题讨论】:

    标签: javascript reactjs vue.js


    【解决方案1】:
        const [state, setState] = useState({
          isScrolling: false,
          clientX: 0, 
          scrollX: 0,
          clientY: 0,
          scrollY: 0 
        });
        ...
        clientY: e.touches[0].clientY
        ...
        const { clientX, scrollX, clientY, scrollY, isScrolling } = state;
        ...
    
          let sY = scrollY - e.touches[0].clientY + clientY;
          let cY = e.touches[0].clientY;
    
          if (sY < -0) {
            sY = 0;
          } else if (sY >= 0 && sY <= 1800) {
            ref.current.scrollTop = sY;
          }
        ...
        scrollY: sY,
        clientY: cY
    

    【讨论】:

    • 我只有一个水平滑动脚本。而垂直是没有脚本的通常滚动,仅当内容不适合页面时才会出现。所以如果我只是滚动页面,我不知道如何阻止水平滑动。
    • 在 div 上使用样式属性:overflow-x: hidden;
    • 它已经在那里),我有一个问题如何确定触摸垂直或水平的位置。
    • 我尝试比较 X 和 Y 坐标之间的差异,但由于 touchMove 事件会定期更新,因此脚本无法正常工作。
    • 比较开始位置和结束位置并找到(endpos - startpos)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多