• 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 };
    }
    
    
  • 相关阅读:
    Class加载顺序
    Java中9大内置基本数据类型Class实例和数组的Class实例(转载)
    java配置日志总结
    Java格式化CST时间(mysql date类型)
    对称二叉树
    模拟--滑动窗口最大值
    group by两个条件
    P1996 约瑟夫问题
    C++命名空间、标准库(std,全局命名空间)
    java中引用对比C++指针
  • 原文地址:https://www.cnblogs.com/xingguozhiming/p/15777906.html
Copyright © 2020-2023  润新知