React高阶组件-属性代理实现PC端拖拽

App.tsx组件

import React from 'react';
import './App.css';
// PC端
import Drag from './hoc/drag';

// 要拖拽的盒子
function Box(){
  return (
    <div className='box'>测试盒子</div>
  )
} 

function Box2(){
  return (
    <div className='box'>测试盒子2</div>
  )
} 

function App() {
  // 定义高阶组件
  let Drags = Drag(Box)
  let Drags2 = Drag(Box2)
  return (
    <div className="App">
      <Drags></Drags>
      <Drags2></Drags2>
    </div>
  );
}

export default App;

  /hoc/Drag.tsx组件--PC端 

import React from "react"

// 高阶组件  属性代理的模式扩展
function Drag(WrapperComponent:any){
        
    return class extends React.Component{
        // 生成随机颜色
        randColor = function(){
            let color:string = "#"
            for(let i = 0;i < 6;i++){
                let num = parseInt(String(Math.random()*16))
                // 转成十六进制
                color += num.toString(16)
            }
            return color
        }

        componentDidMount(): void {
    
            // 可以在这里写拖拽逻辑
            // 获取DOM元素对象
            let dragList = document.querySelectorAll(".drag") as any

            dragList.forEach((drag:any,index:number)=>{
                drag.style.position = "absolute"
                drag.style.backgroundColor = this.randColor()

                let x1:number
                let y1:number
                let l:number
                let t:number

                let drags = function (event:MouseEvent){
                    console.log(event);
                    
                    // 获取鼠标的坐标值对象
                    let x2 = event.clientX
                    let y2 = event.clientY

                    let left = x2 - x1 + l
                    let top = y2 - y1 + t

                    drag.style.left = left + "px"
                    drag.style.top = top + "px"        
                }

                // 绑定鼠标按下事件
                drag?.addEventListener("mousedown",function(event:any){
                    // console.log(event);
                    
                    // 获取鼠标的坐标值对象
                    x1 = event.clientX
                    y1 = event.clientY
                    console.log(x1,y1);

                    // 获取盒子最初的偏移量 offsetLeft offsetTop
                    l = drag.offsetLeft
                    t = drag.offsetTop
                    console.log("鼠标的坐标值",x1,y1,"盒子最初的偏移量",l,t);    
                    
                    

                    drag.addEventListener("mousemove",drags)

                    drag.addEventListener("mouseup",()=>{
                        drag.removeEventListener("mousemove",drags)
                    })
                })
            })
            
            
        }

        render(): React.ReactNode{
            return (
                <div className="drag">
                    <WrapperComponent {...this.props}></WrapperComponent>
                </div>
            )
        }
    }
}

export default Drag

  /hoc/Drag.tsx组件--移动端 

import React from "react";

//高阶组件,属性代理的模式扩展
function DragMobile(WrapperComponent: any) {
    return class extends React.Component<any> {

        //生成一个随机背景颜色的方法
        randColor = function () {
            let color: string = "#";

            for (let i = 0; i < 6; i++) {
                let num = parseInt(String(Math.random() * 16));
                color += num.toString(16);
            }

            return color;
        }

        componentDidMount(): void {
            //可以在这个里面写拖拽的逻辑
            //1. 获取DOM元素对象
            let dragList = document.querySelectorAll(".drag") as any;

            dragList.forEach((drag:HTMLElement, index:number) => {
                drag.style.position = "absolute";
                drag.style.background = this.randColor();

                //初始化一些用到的变量的值。
                let x1: number, x2: number, y1: number, y2: number, l: number, t: number;

                //盒子可以移动左右范围
                let html = document.documentElement || document.body;
                let maxW = html.clientWidth - drag.clientWidth;

                //定义函数封装逻辑,
                let drags = function (event: TouchEvent) {
                    //先获取鼠标的坐标值对象
                    x2 = event.targetTouches[0].pageX;
                    y2 = event.targetTouches[0].pageY;
                    //盒子移动的位置
                    let left = x2 - x1 + l;
                    let top = y2 - y1 + t;

                    if(left<=0){
                        left = 0;
                    }

                    if(top<=0){
                        top =0;
                    }

                    if(left>=maxW){
                        left = maxW
                    }

                    drag.style.left = left + "px";
                    drag.style.top = top + "px";
                };

                //绑定鼠标按下事件
                drag?.addEventListener("touchstart", function (event: TouchEvent) {
                    console.log(event);
                    //先获取鼠标的坐标值对象
                    x1 = event.targetTouches[0].pageX;
                    y1 = event.targetTouches[0].pageY;
                    console.log(x1, y1);

                    // console.log((drag as any).offsetLeft);
                    //获取盒子最初的偏移量 offsetLeft offetTop
                    // let l = (this as any).offsetLeft;
                    l = drag.offsetLeft;
                    t = drag.offsetTop;
                    console.log(x1, y1, l, t);

                    //mousemove鼠标移动
                    drag.addEventListener("touchmove", drags)

                    drag.addEventListener("touchend", () => {
                        drag.removeEventListener("touchmove", drags);
                    })
                })
            })

        }

        render(): React.ReactNode {
            return (
                <div className="drag">
                    <WrapperComponent {...this.props}></WrapperComponent>
                </div>
            )
        }
    }
}


export default DragMobile;

  • 8
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿CCC

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值