Vue 拖动菜单上面的 Title , 让菜单移动,不跟手原因,请教

目的: 拖动菜单上面的 Title , 让菜单移动.

问题描述:
1\ 拖动时不很跟手,晃动感. (手和菜单没粘住的感觉)
2 有时鼠标移出了菜单,菜单却没跟过来

3,请教更好的写法
请教问题出在哪**
**


  <div>
        <div class="color-picker-title" @mousedown.left="colorMenuMouseDown($event)">拖动这里</div>
        <div>菜单内容</div>
   </div>

/ 菜单拖动
let initMeunLeft = 0; // 菜单初始位置
let initMenuTop = 0;
let menuDOM: HTMLDivElement; // 整个菜单
let menuBar: HTMLDivElement  // 菜单上面的 div,点击拖动
function colorMenuMouseDown(event: MouseEvent) {
  console.log('1', event)
  initPointX = event.clientX // 鼠标点下的位置
  initPointY = event.clientY
  menuBar = event.target as HTMLDivElement
  menuDOM = menuBar.parentElement as HTMLDivElement // 父元素是整个菜单
  initMeunLeft = menuDOM.offsetLeft
  initMenuTop = menuDOM.offsetTop
  menuBar.addEventListener('mousemove', colorMenuMouseMove) // 给菜单上面的 title 加上 事件
  menuBar.addEventListener('mouseup', colorMenuMouseUp)
}
function colorMenuMouseMove(event: MouseEvent) {
  const moveWidth = event.clientX - initPointX // 移动的距离
  const moveHeight = event.clientY - initPointY // 
  menuDOM.style.left = initMeunLeft + moveWidth + 'px' // 更新菜单的位置
  menuDOM.style.top = initMenuTop + moveHeight + 'px'
  console.log('2', menuDOM)
}
function colorMenuMouseUp(event: MouseEvent) {
  console.log('3', event)
  menuBar.removeEventListener('mousemove', colorMenuMouseMove)
  menuBar.removeEventListener('mouseup', colorMenuMouseUp)
}



  #color-Picker {
    position: absolute;
    top: 100px;
    z-index: 3;

    .color-picker-title {
      background-color: rgb(160, 164, 168);
      &:hover {
        cursor: pointer;
      }
    }
  }

mousemove 和 mouseup事件应该绑定到document元素上
不能绑定到当前拖动的元素上,否则当鼠标快速移出菜单,mousemove 和 mouseup事件就不会触发了

let initMeunLeft = 0; // 菜单初始位置
let initMenuTop = 0;
let menuDOM: HTMLDivElement; // 整个菜单
let menuBar: HTMLDivElement  // 菜单上面的 div,点击拖动
function colorMenuMouseDown(event: MouseEvent) {
  console.log('1', event)
  initPointX = event.clientX // 鼠标点下的位置
  initPointY = event.clientY
  menuBar = event.target as HTMLDivElement
  menuDOM = menuBar.parentElement as HTMLDivElement // 父元素是整个菜单
  initMeunLeft = menuDOM.offsetLeft
  initMenuTop = menuDOM.offsetTop
  //mousemove 和 mouseup事件应该绑定到document元素上
  document.addEventListener('mousemove', colorMenuMouseMove) // 给菜单上面的 title 加上 事件
  document.addEventListener('mouseup', colorMenuMouseUp)
  event.preventDefault() //加上这个防止内容被选中
}
function colorMenuMouseMove(event: MouseEvent) {
  const moveWidth = event.clientX - initPointX // 移动的距离
  const moveHeight = event.clientY - initPointY // 
  menuDOM.style.left = initMeunLeft + moveWidth + 'px' // 更新菜单的位置
  menuDOM.style.top = initMenuTop + moveHeight + 'px'
  console.log('2', menuDOM)
  event.preventDefault() //加上这个防止内容被选中
}
function colorMenuMouseUp(event: MouseEvent) {
  console.log('3', event)
  //mousemove 和 mouseup事件应该绑定到document元素上
  document.removeEventListener('mousemove', colorMenuMouseMove)
  document.removeEventListener('mouseup', colorMenuMouseUp)
}

这是我之前写的一个拖动代码.参考下

<!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=11,chrome=1" />
    <title> 页面名称 </title>
<style type="text/css">
#cf {
    background-color: #c99;
}

#kkk {
    position: absolute;
    left: 100px;
    top: 400px;
    width: 200px;
    height: 100px;
    background-color: #f9c;
}

.range {
    width: 300px;
    height: 20px;
    border-radius: 20px;
    border: 2px solid #66f;
    background-color: #ccf;
}
.range .slider {
    width: 20px;
    height: 20px;
    border-radius: 20px;
    background-color: #f00;
}
</style>
</head>
<body>

<canvas id="cf" width="400" height="350"></canvas>

<div class="range"><div class="slider"></div></div>

<div id="kkk"></div>

<script type="text/javascript">
!function () {
    function Drag(opt) {
        this.el = typeof opt.el=="string" ? document.querySelector(opt.el) : opt.el;
        this.start = opt.start || function(){};
        this.move = opt.move || function(){};
        this.end = opt.end || function(){};
        this.el.style.touchAction = opt.touchAction || "none";
        this.startEvent = this.startFun.bind(this);
        this.moveEvent = this.moveFun.bind(this);
        this.endEvent = this.endFun.bind(this);
        this.dragging = false;
        this.startPos = null;
        this.prevPos = null;
        this.moveBindEl = Drag.isTouch ? this.el : document;
        this.el.addEventListener(Drag.eventType.start, this.startEvent, false);
    }
    Drag.isTouch = "ontouchstart" in document;
    Drag.eventType = Drag.isTouch
        ? { start: "touchstart", move: "touchmove", end: "touchend" }
        : { start: "mousedown" , move: "mousemove", end: "mouseup" };
    Drag.prototype.startFun = function (e) {
        if (this.dragging) return;
        this.moveBindEl.addEventListener(Drag.eventType.move, this.moveEvent, false);
        this.moveBindEl.addEventListener(Drag.eventType.end, this.endEvent, false);
        this.dragging = true;
        var pos = this.position(e);
        this.startPos = pos;
        if (this.start.call(this.el,e,pos,this)!==true && !Drag.isTouch)
            e.preventDefault();
        this.prevPos = pos;
    };
    Drag.prototype.moveFun = function (e) {
        if (!this.dragging) return;
        var pos = this.position(e);
        if (this.move.call(this.el,e,pos,this)!==true && !Drag.isTouch)
            e.preventDefault();
        this.prevPos = pos;
    };
    Drag.prototype.endFun = function (e) {
        if (!this.dragging) return;
        this.moveBindEl.removeEventListener(Drag.eventType.move, this.moveEvent, false);
        this.moveBindEl.removeEventListener(Drag.eventType.end, this.endEvent, false);
        this.dragging = false;
        if (e) {
            var pos = e!==true ? this.position(e) : this.prevPos;
            this.end.call(this.el,e,pos,this);
        }
    };
    Drag.prototype.position = function (e) {
        var et = Drag.isTouch ? e[e.type!="touchend"?"targetTouches":"changedTouches"][0] : e;
        var pos = {
            screenX: et.screenX,
            screenY: et.screenY,
            clientX: et.clientX,
            clientY: et.clientY,
            pageX: et.pageX,
            pageY: et.pageY
        };
        pos.offset = this.offset.bind(this,pos);
        return pos;
    };
    Drag.prototype.offset = function (et,obj) {
        obj = obj || this.el;
        var r = obj.getBoundingClientRect();
        return {
            x: et.clientX - r.left,
            y: et.clientY - r.top
        };
    };

    window.Drag = Drag;
}();


///////////////////////////////////////

var canvas = document.getElementById("cf");
var ctx = canvas.getContext("2d");
ctx.lineWidth = 3;
ctx.lineCap= "round";

var obj = new Drag({
    el: canvas,
    start: function (e,pos,t) {
    },
    move: function (e,pos,t) {
        var p0 = t.prevPos.offset();
        var p1 = pos.offset();
        ctx.beginPath();
        ctx.moveTo(p0.x,p0.y);
        ctx.lineTo(p1.x,p1.y);
        ctx.stroke();
    },
    end: function (e,pos,t) {
    }
});

/////////////////////////////////////////

var uk = {};
var obj2 = new Drag({
    el: "#kkk",
    start: function (e,pos,t) {
        uk = pos.offset();
    },
    move: function (e,pos,t) {
        this.style.left = pos.pageX - uk.x + "px";
        this.style.top  = pos.pageY - uk.y + "px";
    },
    end: function (e,pos,t) {
    }
});

//////////////////////////////////////////////


var obj3 = new Drag({
    el: ".range",
    touchAction: "pan-y",
    start: function (e,pos,t) {
    },
    move: function (e,pos,t) {
        var p = pos.offset();
        var obj = this.querySelector(".slider");
        var max = this.clientWidth - obj.offsetWidth;
        var x = Math.max(Math.min(p.x - Math.floor(obj.offsetWidth/2),max),0);
        obj.style.marginLeft = x + "px";
    },
    end: function (e,pos,t) {
    }
});


</script>
</body>
</html>
您好,我是有问必答小助手,您的问题已经有小伙伴帮您解答,感谢您对有问必答的支持与关注!
PS:问答VIP年卡 【限时加赠:IT技术图书免费领】,了解详情>>> https://vip.csdn.net/askvip?utm_source=1146287632