react使用hooks自定义插槽拖动组件

组件核心代码
// style.module.less
box-sizing: border-box;
min-width: 50px;
min-height: 50px;
z-index: 3;
import React, { ReactNode, useRef } from 'react';
import style from './style.module.less';
interface PropsType {
    clasName?: string;
    children: {
        header: ReactNode;
        main: ReactNode;
    };
    position?: string;
    top?: number;
    left?: number;
  }
DragSlot.defaultProps = {
    position: 'fixed',
    top: 0,
    left: 0,
}
export default function DragSlot(props: PropsType) {
    const curRef = useRef(null);
    const {position, top, left} = props;
    const curPosition = position === 'fixed' ? 'fixed' : position === 'absolute' ? 'absolute' : 'fixed';
    const curTop = typeof top === 'number' ? top : 0;
    const curLeft = typeof left === 'number' ? left : 0;
    const methods = {
        handleMouseDown(e: React.MouseEvent) {
            // 解决拖动的时候文字会被选中问题
            document.onselectstart = function() {return false;}
            const currentRef: any = curRef.current;
            // 当前元素宽度高度
            const curWidth = currentRef.clientWidth;
            const curHeight = currentRef.clientHeight;
            e = e || window.event
            // 鼠标相对于盒子的位置
            var offsetX = e.clientX - currentRef.offsetLeft;
            var offsetY = e.clientY - currentRef.offsetTop;
            // 可见区域的高度和宽度
            var screenWidth = document.body.offsetWidth - curWidth;
            var screenHeight = document.body.offsetHeight - curHeight;
            // 鼠标移动
            document.onmousemove = function (e) {
                e = e || window.event;
                var left = e.clientX - offsetX;
                var top = e.clientY - offsetY;
                currentRef.style.left = (left < 0 ? 0 : (screenWidth - left < 0 ? screenWidth : left)) + "px";
                currentRef.style.top = (top < 0 ? 0 : (screenHeight - top < 0 ? screenHeight : top)) + "px";
            }
            // 鼠标抬起
            document.onmouseup = function () {
                document.onmousemove = null;
                document.onmouseup = null;
                document.onselectstart = null;
                if (currentRef.releaseCapture) {
                    currentRef.releaseCapture(); // 释放全局捕获   
                }
                // 解决拖动会选中文字的问题
            }
            return false;
        }
    }
    return (<div className={`${props.clasName} ${style.root}`} 
    style={{position: `${curPosition}`, top: `${curTop}`, left: `${curLeft}`}}
        ref={curRef}>
        <div onMouseDown={(event) => {methods.handleMouseDown(event)}}>
            {props.children.header}
        </div>
        <div>
            {props.children.main}
        </div>
    </div>)
};
组件使用
import DragSlot from '@/views/Components/DragSlot';
 <DragSlot >{{
    header: (<>
        我是自定义头部
    </>),
    main: (<>
        我是主要内容
    </>)
}}</DragSlot>
  • 14
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值