0411

93 阅读1分钟

关于拖拽计算;

image.png

image.png

image.png

image.png 问题: 只是按下,还没等move就触发了move方法 image.png

修改

image.png 还有个问题: 鼠标焦点丢失问题

image.png

代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        html,body{
            height: 100%;
            overflow: hidden;
        }
        .box{
            position: absolute;
            top: 0;
            left: 0;
            width: 100px;
            height: 100px;
            display: inline-block;
            background-color: red;
            cursor: move;
        }
    </style>
</head>
<body>
    <div class="box" id="box"></div>
    <script>
         box.onmousedown = down;
        function down(ev){
            this.startX=ev.pageX;
            this.startY=ev.pageY;
            this.startL = this.offsetLeft;
            this.startT= this.offsetTop;
            // 按下来再给盒子绑定move方法
            // 谷歌中解决鼠标焦点丢失问题(别绑定给盒子了,绑定给document),但是要注意
            // move中的this已经是document了,而不是之前的Box,我们需处理下
            document.onmousemove = move.bind(this)
            document.onmouseup = up.bind(this);
            // 把鼠标和盒子绑在一起

        }
        function move(ev){
            // 随时获取当前鼠标的信息,计算盒子最新的位置
            let curL = ev.pageX - this.startX + this.startL,
            curT = ev.pageY - this.startY + this.startT;
            //边界判断
            let minL =0,
            minT=0,
            maxL = document.documentElement.clientWidth - this.offsetWidth,
            maxT = document.documentElement.clientHeight - this.offsetHeight;
            curL = curL<minL?minL:(curL>maxL?maxL:curL);
            this.style.left=curL + 'px';
            this.style.top=curT+'px';
        }
        function up(ev){
            // 鼠标抬起,move移除
            document.onmousemove = null;
            document.onmouseup= null;

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

DOM2实现:

 <script>
        //鼠标只要在盒子上移动,鼠标移动多远 盒子也移动多远
        
        let css = function(curEle,attr){
            return parseFloat(window.getComputedStyle(curEle,null)[attr])
        }
        // 拿到元素所有被浏览器计算过的样式 不能.attr 存的值 
         let down = function(ev){
             this.startX = ev.pageX;
             this.startY = ev.pageY;
            this.startL = css(this,'left');//也可以offsetLeft,top(相对于body定位)
            this.startT = css(this,'top');
            this.addEventListener('mousemove',move)
            this.addEventListener('mouseup',up)
         }
         let move = function(ev){
            let curL= ev.pageX-this.startX+ this.startL,
                curT = ev.pageY-this.startY +this.startT;
                // 边界判断 
                let minL=0,minT =0,
                maxL=document.documentElement.clientWidth - this.offsetWidth;
                maxT = document.documentElement.clientHeight-this.offsetHeight;
                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'
         }
         let up = function(ev){
            this.removeEventListener('mousemove',move)
            this.removeEventListener('mouseup',up)
         }
         box.addEventListener('mousedown',down)
    </script>

但是上述方法存在如果鼠标移动过快盒子就跟不上的问题

盒子外触发的mouseup

解决:事件绑定在document上

代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        html,body{
            height: 100%;
            overflow: hidden;
        }
        .box{
            position: absolute;
            top: 0;
            left: 0;
            width: 100px;
            height: 100px;
            display: inline-block;
            background-color: red;
            cursor: move;
        }
    </style>
</head>
<body>
    <div class="box" id="box"></div>
    <script>
        //鼠标只要在盒子上移动,鼠标移动多远 盒子也移动多远
        
        let css = function(curEle,attr){
            return parseFloat(window.getComputedStyle(curEle,null)[attr])
        }
        // 拿到元素所有被浏览器计算过的样式 不能.attr 存的值 
         let down = function(ev){
             this.startX = ev.pageX;
             this.startY = ev.pageY;
            this.startL = css(this,'left');//也可以offsetLeft,top(相对于body定位)
            this.startT = css(this,'top');
            this._MOVE = move.bind(this)
            this._UP = up.bind(this)
            document.addEventListener('mousemove',this._MOVE)
            document.addEventListener('mouseup', this._UP)
         }
         let move = function(ev){
            let curL= ev.pageX-this.startX+ this.startL,
                curT = ev.pageY-this.startY +this.startT;
                // 边界判断 
                let minL=0,minT =0,
                maxL=document.documentElement.clientWidth - this.offsetWidth;
                maxT = document.documentElement.clientHeight-this.offsetHeight;
                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'
         }
         let up = function(ev){
            document.removeEventListener('mousemove', this._MOVE)
            document.removeEventListener('mouseup', this._UP)
              //继续做的事情
            //   let minL = container.offsetLeft,
            // minT = container.offsetTop,
            // maxL=minL+container.offsetWidth-this.offsetWidth,
            // maxT=minT+container.offsetHeight-this.offsetHeight,
            // curL = css(this,'left')
            // curT = css(this,'top')
            // if((curL>=minL&&curL<=maxL)&&(curT>=minT&&curT<=maxT)){
            //     // 在指定的范围内
            //     return
            // }
            // // 没有拖到指定范围内
            // this.style.left =this.startL+'px'
            // this.style.top =this.startT+'px'
         }
         box.addEventListener('mousedown',down)
    </script>
</body>
</html>