IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> react 优雅处理多条件鼠标拖拽位移 -> 正文阅读

[JavaScript知识库]react 优雅处理多条件鼠标拖拽位移

在这里插入图片描述
场景
三种拖拽条件 可纵轴 横轴 和全部方向 如果加3个监听重复代码太多
因为状态更改组件会重新渲染 所以写的时候要多注意避免有大量代码的函数多次创建销毁

state

const [position, setPosition] = useState(axisPosition);

jsx

<Container
      style={{
        top: position.top + "px",
        left: position.left + "px",
      }}
    >
      <div>
        <span
          onMouseDown={handleDown(position, (p) => {
            setPosition({ ...p, left: position.left });
          })}
        ></span>
        <div onMouseDown={handleDown(position, setPosition)}></div>
        <span
          onMouseDown={handleDown(position, (p) => {
            setPosition({ ...p, top: position.top });
          })}
        ></span>
      </div>
    </Container>

监听

const handleDown =
  (position: IPosition, setState: (position: IPosition) => void) => (e: React.MouseEvent<HTMLElement, MouseEvent>) => {
    const startX = e.pageX;
    const startY = e.pageY;
    const { top, left } = position;
    const move = (ev: MouseEvent) => {
      const disX = ev.pageX - startX;
      const disY = ev.pageY - startY;
      setState({ left: left + disX, top: top + disY });
    };

    const cancel = () => {
      document.removeEventListener("mousemove", move);
      document.removeEventListener("mouseup", cancel);
      document.removeEventListener("mouseleave", cancel);
    };

    document.addEventListener("mousemove", move);
    document.addEventListener("mouseup", cancel);
    document.addEventListener("mouseleave", cancel);
  };

业务代码

/*
 * @Author: hongbin
 * @Date: 2022-04-03 13:38:02
 * @LastEditors: hongbin
 * @LastEditTime: 2022-04-03 21:49:42
 * @Description:移动坐标轴
 */
import { FC, ReactElement, useEffect, useState } from "react";
import styled from "styled-components";
import { useElementContext } from "../../context/ElementContext";
import { flexCenter } from "../../styled";

interface IProps {}

interface IPosition {
  top: number;
  left: number;
}

const handleDown =
  (position: IPosition, setState: (position: IPosition) => void) => (e: React.MouseEvent<HTMLElement, MouseEvent>) => {
    const startX = e.pageX;
    const startY = e.pageY;
    const { top, left } = position;
    const move = (ev: MouseEvent) => {
      const disX = ev.pageX - startX;
      const disY = ev.pageY - startY;
      setState({ left: left + disX, top: top + disY });
    };

    const cancel = () => {
      document.removeEventListener("mousemove", move);
      document.removeEventListener("mouseup", cancel);
      document.removeEventListener("mouseleave", cancel);
    };

    document.addEventListener("mousemove", move);
    document.addEventListener("mouseup", cancel);
    document.addEventListener("mouseleave", cancel);
  };

const Axis: FC<IProps> = (): ReactElement => {
  const { axisPosition } = useElementContext();
  const [position, setPosition] = useState<IPosition>(axisPosition);

  useEffect(() => {
    setPosition(axisPosition);
  }, [axisPosition]);

  return (
    <Container
      style={{
        top: position.top + "px",
        left: position.left + "px",
      }}
    >
      <div>
        <span
          onMouseDown={handleDown(position, (p) => {
            setPosition({ ...p, left: position.left });
          })}
        ></span>
        <div onMouseDown={handleDown(position, setPosition)}></div>
        <span
          onMouseDown={handleDown(position, (p) => {
            setPosition({ ...p, top: position.top });
          })}
        ></span>
      </div>
    </Container>
  );
};

export default Axis;

const Container = styled.div`
  position: absolute;
  z-index: 99999;
  transform: translateX(-6px);
  & > div {
    background: #c711ff;
    width: 0px;
    height: 0px;
    border-radius: 0px;
    border: 3px solid #c711ff;
    position: relative;
    ${flexCenter};
    span {
      position: absolute;
      :first-child {
        cursor: ns-resize;
        background-color: red;
        width: 2px;
        height: 3vw;
        transform: translateY(-60%);
        ::before {
          content: "";
          border: 4px solid red;
          top: 0;
          left: -3px;
          position: absolute;
          transform: scaleY(4) rotate(180deg);
          border-left-color: transparent;
          border-bottom-color: transparent;
          border-right-color: transparent;
          transform-origin: top;
        }
      }
      :last-child {
        cursor: ew-resize;
        width: 3vw;
        height: 2px;
        background-color: blue;
        transform: translateX(60%);
        ::before {
          content: "";
          border: 4px solid blue;
          top: -3px;
          right: 0;
          position: absolute;
          transform: scaleX(4) rotate(-90deg) translateY(50%);
          border-left-color: transparent;
          border-right-color: transparent;
          border-bottom-color: transparent;
        }
      }
    }
    div {
      cursor: move;
      width: inherit;
      height: inherit;
      border: inherit;
      border-radius: inherit;
      background-color: inherit;
      position: absolute;
      z-index: 1;
    }
  }
`;

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-04 12:02:05  更:2022-04-04 12:02:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:36:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码