满口金牙 2022-07-07 18:36 采纳率: 91.5%
浏览 62
已结题

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;
      }
    }
  }
  • 写回答

2条回答 默认 最新

  • 关注

    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>
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 7月17日
  • 已采纳回答 7月9日
  • 修改了问题 7月7日
  • 修改了问题 7月7日
  • 展开全部

悬赏问题

  • ¥20 求数据集和代码#有偿答复
  • ¥15 关于下拉菜单选项关联的问题
  • ¥20 java-OJ-健康体检
  • ¥15 rs485的上拉下拉,不会对a-b<-200mv有影响吗,就是接受时,对判断逻辑0有影响吗
  • ¥15 使用phpstudy在云服务器上搭建个人网站
  • ¥15 应该如何判断含间隙的曲柄摇杆机构,轴与轴承是否发生了碰撞?
  • ¥15 vue3+express部署到nginx
  • ¥20 搭建pt1000三线制高精度测温电路
  • ¥15 使用Jdk8自带的算法,和Jdk11自带的加密结果会一样吗,不一样的话有什么解决方案,Jdk不能升级的情况
  • ¥15 画两个图 python或R