• react实现自定义hooks(移动端拖拽)


    实现思路

    通过touchstart、touchmove、touchend组合,实现过程中需要注意以下几个问题

    1. touchmove、touchend事件需要绑定在window上,并且这两个事件需要包在touchstart中
    2. touchstart事件需要阻止冒泡和禁止默认事件,开始监听touchmove和touchmove。组件销毁前要记得移除事件监听
    3. touchend事件里要移除事件监听
    4. touchmove计算位置值,弄清楚event.clientX和element.offsetTop等关系
    5. 定位不要使用position,应该使用transform的translate

    在线预览

    react移动端拖拽hooks

    核心代码

    import { useEffect, useState, useRef } from "react";
    import "./styles.css";
    /***
     * 请在移动端查看
     */
    const docWidth = document.documentElement.clientWidth;
    const docHeight = document.documentElement.clientHeight;
    
    export default function useMobileDrag(props) {
      const touchStartX = useRef(0);
      const touchStartY = useRef(0);
      const [x, setX] = useState(0);
      const [y, setY] = useState(0);
    
      const { targetDomRef } = props;
    
      useEffect(() => {
        if (!targetDomRef?.current) {
          return;
        }
    
        const target = targetDomRef.current;
        const { width, height } = target.getBoundingClientRect();
        const touchmove = (e) => {
          const { clientX, clientY } = e.targetTouches[0];
          if (clientX - touchStartX.current >= docWidth - width) {
            setX(docWidth - width);
          } else if (clientX - touchStartX.current <= 0) {
            setX(0);
          } else {
            setX(clientX - touchStartX.current);
          }
          if (clientY - touchStartY.current >= docHeight - height) {
            setY(docHeight - height);
          } else if (clientY - touchStartY.current <= 0) {
            setY(0);
          } else {
            setY(clientY - touchStartY.current);
          }
        };
        const touchend = () => {
          window.removeEventListener("touchmove", touchmove);
          window.removeEventListener("touchend", touchend);
        };
        const touchstart = (e) => {
          e.stopPropagation();
          e.preventDefault();
          const { top, left } = target?.getBoundingClientRect();
          const { clientX, clientY } = e.targetTouches[0];
          touchStartX.current = clientX - left;
          touchStartY.current = clientY - top;
    
          window.addEventListener("touchmove", touchmove);
          window.addEventListener("touchend", touchend);
        };
        target.addEventListener("touchstart", touchstart);
        return () => {
          target.removeEventListener("touchstart", touchstart);
        };
      }, [targetDomRef]);
      return { x, y };
    }
    
    
  • 相关阅读:
    Winform中在ZedGraph中最多可以添加多少条曲线(转)
    c#委托的含义和用法
    vs2010打开vs2017工程
    C# Socket编程资源
    C# 调用打印机 打印 Excel (转)
    NPOI 教程
    C# 调用C++ DLL 的类型转换(转载版)(转)
    进程间通信(网络阅读笔记)
    NPOI 第二篇 设置样式与合并单元格(转)
    分布式事务的 6 种解决方案,写得非常好!
  • 原文地址:https://www.cnblogs.com/xingguozhiming/p/15777906.html
Copyright © 2020-2023  润新知