拖拽实现

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        html,body{
            width: 100%;
            height: 400%; 
            /* skyblue; */
        }

        
        .box{
            position: fixed;
            top: 100px;
            left: 200px;
            width: 100px;
            height: 100px;
            background-color: lightblue;
            cursor: move;
        }
        .container-1{
            height: 1000px;
            border: 1px solid red;
        }
        .container-2{
            height: 1000px;
            border: 1px solid blue ;
        }
    </style>
</head>
<body>

    <div class="container-1">2323</div>  
    <div class="container-2">2323</div> 
    <div class="box"></div>  

    <script>

        /** 
         * 拖拽的思路  
         *   鼠标开始位置 A
         *   鼠标当前位置 B (鼠标移动中随时计算)
         *   盒子开始位置 C
         *   
         *   盒子当前位置 D = (B-A) + C
         * 
         *   拖拽触发的条件
         *     1 鼠标按住盒子才开始拖动,鼠标只要抬起则结束拖拽
         *     2 拖拽开始后,鼠标移动盒子才会跟着移动的
         * 
         *     鼠标按住盒子 mousedown
         *        + 记录C
         *        + 记录A
         * 
         *     鼠标移动 mousemove
         *        + 获取B
         *        + 动态计算出D
         *        + 修改盒子的样式,从而让盒子跟着移动
         *  
         *      鼠标抬起 mouseup
         *        + 取消拖拽
         */


         /**
          *  解决鼠标焦点丢失问题
          *   + (1) IE / 火狐: 把盒子和鼠标绑定在一起
          *     + setCapture
          *     + releaseCapture
          *   + (2) 谷歌
          *      mousemove mouseup 绑定给 window
         */
         let box = document.querySelector('.box');

         // 获取边界值
         let HTML = document.documentElement,
              minL = 0,
              minT = 0,
              maxL = HTML.clientWidth - box.offsetWidth,
              maxT =  HTML.clientHeight - box.offsetHeight;
       
         const down = function down(ev){
            // 记录 鼠标开始位置和盒子的开始位置

            let {top,left} = this.getBoundingClientRect(); 
            this.startT = top;
            this.startL = left;

            // 记录鼠标坐标位置
            this.startX = ev.clientX;
            this.startY = ev.clientY;

            // 鼠标按下才进行事件绑定(拖拽开始)
            // this.setCapture();

            // 保证move / up 中的this 还需要是盒子,
            this._move = move.bind(this);
            this._up = up.bind(this);
            window.addEventListener('mousemove',this._move);
            window.addEventListener('mouseup',this._up); 
         }

         // 鼠标移动拖拽中
         const move = function move(ev){
             
            // 获取盒子当前的位置
            let curL = ev.clientX - this.startX + this.startL,
                curT = ev.clientY - this.startY + this.startT;

            // 边界判断
            curL = curL < minL ? minL : (curL > maxL ?  maxL : curL) ;
            curT = curT < minT ? minT : (curT > maxT ?  maxT : curT) ;

            // 修改移动位置
            this.style.left = `${curL}px`;
            this.style.top  = `${curT}px`; 
         }

         // 鼠标抬起拖拽结束
         const up = function up(ev){ 
            // 移除事件绑定
            // this.releaseCapture();
            window.removeEventListener('mousemove',this._move);
            window.removeEventListener('mouseup',this._up); 
         }

         box.addEventListener('mousedown',down); 

         // 获取 当前盒子信息  视口/位置
        //  console.log(box.getBoundingClientRect());
    </script>
</body>
</html>
posted @ 2021-08-02 14:00  13522679763-任国强  阅读(44)  评论(0)    收藏  举报