zoukankan      html  css  js  c++  java
  • 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 };
    }
    
    
  • 相关阅读:
    Sample Page
    3.21之前刷题总结
    存储过程动态组建查询where语句
    SQL常备知识
    学习SilverLight:(1)SilverLight3.0和JavaScript交互
    SQL SERVER 2005 Tempdb
    学习atlas
    sql server系统表详细说明(转)
    js 基数排序的过程
    vuerouter 刷新页面后 url地址不变 参数还在 保留当前页 routerlink取值 this.$route
  • 原文地址:https://www.cnblogs.com/xingguozhiming/p/15777906.html
Copyright © 2011-2022 走看看