react優(yōu)雅處理多條件鼠標(biāo)拖拽位移
本文實(shí)例為大家分享了react優(yōu)雅處理多條件鼠標(biāo)拖拽位移的具體代碼,供大家參考,具體內(nèi)容如下
場景
三種拖拽條件 可縱軸 橫軸 和全部方向 如果加3個(gè)監(jiān)聽重復(fù)代碼太多
因?yàn)闋顟B(tài)更改組件會(huì)重新渲染 所以寫的時(shí)候要多注意避免有大量代碼的函數(shù)多次創(chuàng)建銷毀
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>
監(jiān)聽
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); ? };
業(yè)務(wù)代碼
/* ?* @Author: hongbin ?* @Date: 2022-04-03 13:38:02 ?* @LastEditors: hongbin ?* @LastEditTime: 2022-04-03 21:49:42 ?* @Description:移動(dòng)坐標(biāo)軸 ?*/ 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; ? ? } ? } `;
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
React?中使用?RxJS?優(yōu)化數(shù)據(jù)流的處理方案
這篇文章主要為大家介紹了React?中使用?RxJS?優(yōu)化數(shù)據(jù)流的處理方案示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02React中super()和super(props)的區(qū)別小結(jié)
本文主要介紹了React中super()和super(props)的區(qū)別小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-03-03React中hook函數(shù)與useState及useEffect的使用
這篇文章主要介紹了React中hook函數(shù)與useState及useEffect的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-10-10react?native?reanimated實(shí)現(xiàn)動(dòng)畫示例詳解
這篇文章主要為大家介紹了react?native?reanimated實(shí)現(xiàn)動(dòng)畫示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03react中路由跳轉(zhuǎn)及傳參的實(shí)現(xiàn)
本文主要介紹了react中路由跳轉(zhuǎn)及傳參的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05React中使用Workbox進(jìn)行預(yù)緩存的實(shí)現(xiàn)代碼
Workbox是Google Chrome團(tuán)隊(duì)推出的一套 PWA 的解決方案,這套解決方案當(dāng)中包含了核心庫和構(gòu)建工具,因此我們可以利用Workbox實(shí)現(xiàn)Service Worker的快速開發(fā),本文小編給大家介紹了React中使用Workbox進(jìn)行預(yù)緩存的實(shí)現(xiàn),需要的朋友可以參考下2023-11-11