react优雅处理多条件鼠标拖拽位移

 更新时间:2022年08月26日 15:22:25   作者:Jedi Hongbin  
这篇文章主要为大家详细介绍了react优雅处理多条件鼠标拖拽位移,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了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;
    }
  }
`;

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • React使用Props实现父组件向子组件传值

    React使用Props实现父组件向子组件传值

    在React中,组件之间的数据传递通常是通过属性(Props)来实现的,父组件可以通过属性向子组件传递数据,这是React组件通信的基础模式之一,本文将探讨如何使用Props来实现父组件向子组件传递数据,需要的朋友可以参考下
    2025-04-04
  • React配置多个代理实现数据请求返回问题

    React配置多个代理实现数据请求返回问题

    这篇文章主要介绍了React之配置多个代理实现数据请求返回问题,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-08-08
  • React 使用Hooks简化受控组件的状态绑定

    React 使用Hooks简化受控组件的状态绑定

    这篇文章主要介绍了React 使用Hooks简化受控组件的状态绑定,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-03-03
  • React图片压缩上传统一处理方式

    React图片压缩上传统一处理方式

    这篇文章主要介绍了React图片压缩上传统一处理方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • react-router4 嵌套路由的使用方法

    react-router4 嵌套路由的使用方法

    本篇文章主要介绍了react-router4 嵌套路由的使用方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • webpack入门+react环境配置

    webpack入门+react环境配置

    webpack是一个前端资源模块化管理和打包工具,说白了就是方便我们管理自己的常用的一些代码,比如你开发中用到sass以及jade同时用到es6,开发时你不可能改动某个地方就挨个命令去转换再到浏览器去看效果,那样效率是非常低的。所以webpack帮我们省去了那些多余的步骤。
    2017-02-02
  • 解决React报错Invalid hook call

    解决React报错Invalid hook call

    这篇文章主要为大家介绍了React报错Invalid hook call解决方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • React Native基础入门之初步使用Flexbox布局

    React Native基础入门之初步使用Flexbox布局

    React中引入了flexbox概念,flexbox是属于web前端领域CSS的一种布局方案,下面这篇文章主要给大家介绍了关于React Native基础入门之初步使用Flexbox布局的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2018-07-07
  • styled-components 性能详解

    styled-components 性能详解

    这篇文章主要为大家介绍了styled-components 的性能示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • React实现二级联动的方法

    React实现二级联动的方法

    这篇文章主要为大家详细介绍了React实现二级联动的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09

最新评论