div任意边框拖拽布局

117 阅读1分钟

原理

开始拖拽时记录鼠标的clientX,clientY,通过在拖拽时判断鼠标的位移,完成div宽度的设置。

使用

无代码侵入

useEffect(() => {
        const rightCb = enrichDivResizer('yourDivIdWithout#',{right:true})
        return () => {
            rightCb && rightCb();
        }
    },[])

源代码

export function enrichDivResizer(
    id:string,options:{top?:boolean,right?:boolean,bottom?:boolean,left?:boolean}
){
    const target = document.getElementById(id);
    if(!target)return;
    const {top,right,bottom,left} = options ?? {}
    const elements:Array<HTMLDivElement>=[];
    let element:HTMLDivElement;
    let startX:number,startY:number,startWidth:number,startHeight:number;
    function doDrag(e:MouseEvent):void{
        if(top){
            element.style.height = startHeight - (e.clientY - startY) + "px";
        }
        if(bottom){
            element.style.height = startHeight + e.clientY - startY + "px";
        }
        if(right){
            element.style.width = startWidth + e.clientX - startX + "px";
        }
        if(left){
            element.style.width = startWidth - (e.clientX - startX) + "px";
        }
    }
    function stopDrag(e:MouseEvent):void{
        document.documentElement.removeEventListener("mousemove", doDrag, false);
        document.documentElement.removeEventListener("mouseup", stopDrag, false);
    }
    function initDrag(e:MouseEvent):void{
        element = this.parentContainer;
        startX= e.clientX;
        startY= e.clientY;
        startWidth = parseInt(
            (document.defaultView || window).getComputedStyle(element).width,
            10
        );
        startHeight = parseInt(
            (document.defaultView || window).getComputedStyle(element).height,
            10
        );
        document.documentElement.addEventListener("mousemove", doDrag, false);
        document.documentElement.addEventListener("mouseup", stopDrag, false);
    }
    if(top){
        const top = document.createElement('div');
        top.className = "resizer-top";
        top.setAttribute('style','height:5px;width:100%;background: transparent;position: absolute;top:0;left:0;cursor:row-resize;')
        target?.appendChild(top);
        top.addEventListener('mousedown',initDrag,false);
        elements.push(top)
        top.parentContainer = target;
    }
    if(right){
        const right = document.createElement("div");
        right.className = "resizer-right";
        right.setAttribute('style','height:100%;width:5px;background: transparent;position: absolute;bottom:0;right:0;cursor:col-resize;')
        target.appendChild(right);
        right.addEventListener("mousedown", initDrag, false);
        elements.push(right)
        right.parentContainer = target;
    }
    if(bottom){
        const bottom = document.createElement("div");
        bottom.className = "resizer-bottom";
        bottom.setAttribute('style','height:5px;width:100%;background: transparent;position: absolute;bottom:0;left:0;cursor:row-resize;')
        target.appendChild(bottom);
        bottom.addEventListener("mousedown", initDrag, false);
        elements.push(bottom);
        bottom.parentContainer = target;
    }
    if(left){
        const left = document.createElement("div");
        left.className = "resizer-left";
        left.setAttribute('style','height:100%;width:5px;background: transparent;position: absolute;top:0;left:0;cursor:col-resize;')
        target.appendChild(left);
        left.addEventListener("mousedown", initDrag, false);
        elements.push(left);
        left.parentContainer = target;
    }
    return () => {
        elements.forEach(item => {
            item?.removeEventListener('mousedown',initDrag,false)
        });
    }
}