JavaScript div实现拖拽改变宽度

说明

演示网址:

https://www.malaoshi.top/demo/dragWidth.html

如下图:

分析

右侧部分,点击向右移动

修改div的宽度:

div新宽度 = div的原宽度 + 移动的距离

右侧部分,点击向左移动

修改div的宽度:

div新宽度 = div的原宽度 - 移动的距离

左侧部分,点击移动

除了向上面那样修改宽度,还要修改 left ,否则左侧边框无法更改

优化性能

每个div只加一个点击事件,在事件中再增加 移动事件

抬起鼠标时,要即时 移除 移动事件

代码

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title></title>
        <style>
            body{
                margin: 0;
            }
            .square{
                background-color: #5b9bd5;
                /* border: 1px #969696 solid; */
                width: 300px;
                height: 80px;
                position: relative;
                top:50px; /*距离顶部的像素值,相当于y坐标*/
                left:100px; /*距离左侧的像素值,相当于x坐标*/
                border-radius: 10px;
                display: flex;
                /* justify-content: center; */
                align-items: center;
            }
            .square_block {
                width: 5px;
                height: 50%;
                background-color: #3c668c;
                cursor: col-resize;
            }
            .left{
                /* float: left; */
            }
            .right{
                margin-left: auto;
            }
        </style>
    </head>
    <body>
        <div class="square" name="square">
            <div class="square_block left" ></div>
            <div class="square_block right" ></div>
        </div>
        <br>
        <div class="square" name="square">
            <div class="square_block left" ></div>
            <div class="square_block right" ></div>
        </div>
        <br>
        <div class="square" name="square">
            <div class="square_block left" ></div>
            <div class="square_block right" ></div>
        </div>

        <script>
            const squareArr = document.getElementsByName("square")

            function drag(){
                const minWidth = 80
                const maxWidth = 500

                // 点击右侧block移动鼠标事件
                function rightBlockMove(e,square){
                    // 改变方块的宽度
                    const squareRect = square.getBoundingClientRect()
                    const rightBlockRect = square.children[0].getBoundingClientRect()

                    let width = 0
                    // console.log("e.x:",e.x,"     rightBlockRect.left:",rightBlockRect.left)
                    /*
                    * 当鼠标向左移动时,计算如下:
                    * 鼠标移动距离是 = square.right  - 鼠标的x坐标 
                    * 新宽度 = 原宽度  - 鼠标移动距离
                    * 整合计算公式为:新宽度 = 原宽度  - ( square.right  - 鼠标的x坐标 ),
                    * 等价: 原宽度  -  square.right  + 鼠标的x坐标 
                    * 
                    * 
                    * 当鼠标向右移动时,计算如下:
                    * 鼠标移动距离是 = 鼠标的x坐标 - square.right 
                    * 新宽度 = 原宽度  - 鼠标移动距离
                    * 整合计算公式为:新宽度 = 原宽度  - ( 鼠标的x坐标 - square.right ),
                    * 等价: 原宽度  -  square.right  + 鼠标的x坐标 
                    * 
                    * 最终:用一个公式即可算出,即:新宽度 = 原宽度  -  square.right  + 鼠标的x坐标 
                    * 
                    * rightBlockRect.width*0.5 是偏移量,不加该偏移量,移动时,鼠标不在 right_block 的中间位置
                    * 
                    */


                    width = squareRect.width + ( e.x - squareRect.right ) + rightBlockRect.width*0.5

                    if( width<minWidth ){
                        width = minWidth
                    }
                    if(width > maxWidth){
                        width = maxWidth
                    }
                    square.style.width = width +"px"
                    // console.log(", right:",squareRect.right , ",e.x:",e.x,", new width:",width,",old width:",squareRect.width,",( e.x - squareRect.right )::",( e.x - squareRect.right ))


                }
                function leftBlockMove(e,square){
                    const squareRect = square.getBoundingClientRect()
                    const leftBlockRect = square.children[1].getBoundingClientRect()


                    /*
                    * 当鼠标向左移动时,计算如下:
                    * 鼠标移动距离是 = square.left  - 鼠标的x坐标 
                    * 新宽度 = 原宽度  + 鼠标移动距离
                    * left = 原left - 鼠标移动距离
                    * 
                    * 
                    * 当鼠标向右移动时,计算如下:
                    * 鼠标移动距离是 = 鼠标的x坐标 - square.right 
                    * 新宽度 = 原宽度  - 鼠标移动距离
                    * left = 原left + 鼠标移动距离
                    * 
                    * 
                    * leftBlockRect.width*0.5 是偏移量,不加该偏移量,移动时,鼠标不在 left_block 的中间位置
                    * 
                    */

                    // 移动距离
                    const moveLen = e.x - squareRect.left

                    let width = squareRect.width -  moveLen   + leftBlockRect.width*0.5
                    let left = squareRect.left + moveLen - leftBlockRect.width*0.5
                    // console.log("moveLen:",moveLen,", left:",squareRect.left , ",e.x:",e.x ,",width:",width)

                    if( width<minWidth ){ // 如果宽度过小 或 过大,什么都不做
                        width = minWidth
                        left = squareRect.right - width
                    }else if(width > maxWidth){
                        width = maxWidth
                        left = squareRect.right - width
                    }

                    // console.log("left:",left,", width:",width,",right:",squareRect.right)
                    square.style.width = width + "px"
                    square.style.left = left + "px"
                }

                function squareMouseDown(e){
                    // console.log(e,e.currentTarget)
                    const square = e.currentTarget
                    // console.log(e,square.children, square.firstChild, square.lastChild)
                    // 点击事件、移动事件可能会有冲突,所以加延时
                    setTimeout(function(){
                        if(e.target == square.children[0]){
                            // document.addEventListener("mousemove",leftBlockMove,square)

                            function callback(e){
                                leftBlockMove(e,square)
                            }

                            document.addEventListener("mousemove",callback)

                            // 弹起鼠标时,移除这些事件
                            function mouseup(){
                                // console.log("document 鼠标抬起事件")
                                // document.removeEventListener("mousemove",rightBlockMove)
                                document.removeEventListener("mousemove",callback)
                                document.removeEventListener("mouseup",mouseup)
                            }
                            document.addEventListener("mouseup",mouseup)

                        }else if(e.target == square.children[1]){
                            // document.addEventListener("mousemove",rightBlockMove)
                            function callback(e){
                                rightBlockMove(e,square)
                            }
                            document.addEventListener("mousemove",callback)

                            // 弹起鼠标时,移除这些事件
                            function mouseup(){
                                // console.log("document 鼠标抬起事件")
                                // document.removeEventListener("mousemove",rightBlockMove)
                                document.removeEventListener("mousemove",callback)
                                document.removeEventListener("mouseup",mouseup)
                            }

                            document.addEventListener("mouseup",mouseup)
                        }
                    },80)

                }
                return squareMouseDown
            }

            const dragFun = drag()
            for( let item of squareArr){
                item.addEventListener("mousedown",dragFun)
            }


        </script>
    </body>
</html>

原文出处:/show_1IX8d3tfyXWe.html