vue+mousemove实现鼠标拖动功能(拖动过快失效问题解决方法)


Posted in Javascript onAugust 24, 2018

今天用vue+原生js的mousemove事件,写了个拖动,发现只能慢慢拖动才行,鼠标只要移动快了,就失效,不能拖动了;

搞了半天在,总算解决了,但是问题的深层原理还没搞清楚,知道的大侠可以留言分享,下面直接上代码:

只能慢速拖动的代码:

<!DOCTYPE html>
<html>
<head>
 <title>vue结合原生js实现拖动</title>
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
</head>
<body>
<div id="app">
<div class="ctn ctn1">
 <div class="sub sub1" v-for="(site, index) in list1">
   <div class="dragCtn fixed" @mousedown="mousedown(site, $event)" @mousemove.prevent='mousemove(site, $event)' @mouseup='mouseup(site, $event)'>
   {{ site.name }}
   </div>
 </div>
</div>
<div class="ctn ctn2">
 <div class="sub sub2" v-for="(site, index) in list2">
   <div class="dragCtn">
    {{ index }} : {{ site.name }}
   </div>
 </div> 
</div> 
</div>
<script>
new Vue({
 el: '#app',
 data: {
 list1: [{name:'拖动我', index:0}],
 list2: [{name:'a', index:0}, {name:'b', index:1}, {name:'c', index: 2}, {name:'d', index: 3}],
 vm:'',
 sb_bkx: 0,
 sb_bky: 0,
 is_moving: false
 },
 methods: {
  mousedown: function (site, event) {
  var startx=event.x;
  var starty=event.y;
  this.sb_bkx=startx - event.target.offsetLeft;
  this.sb_bky=starty - event.target.offsetTop;
  this.is_moving = true;
  },
  mousemove: function (site, event) {
   var endx=event.x - this.sb_bkx;
  var endy=event.y - this.sb_bky;
  var _this = this
  if(this.is_moving){
   event.target.style.left=endx+'px';
   event.target.style.top=endy+'px';
  }
  },
  mouseup: function (e) {
  this.is_moving = false;
  }
 }
})
</script>
<style>
 .ctn{
  line-height: 50px;
  cursor: pointer;
  font-size: 20px;
  text-align: center;
  float: left;
 }
 .sub:hover{
  background: #e6dcdc;
  color: white;
  width: 100px;
 }
  .ctn1{
   border: 1px solid green;
   width: 100px;
  }
  .ctn2{
   border: 1px solid black;
   width: 100px;
   margin-left: 50px;
  }
  .fixed{
   width: 100px;
   height: 100px;
  position: fixed;
  background: red;
  left: 10px;
  top: 10px;
  cursor: move;
  }
</style>
</body>
</html>

可以快速拖动的代码:

<!DOCTYPE html>
<html>
<head>
 <title>vue结合原生js实现拖动</title>
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
</head>
<body>
<div id="app">
<div class="ctn ctn1">
<!-- draggable=true -->
 <div class="sub sub1" v-for="(site, index) in list1">
 <!-- @mousemove.prevent='mousemove(site, $event)' -->
   <div class="dragCtn fixed" @mousedown="mousedown(site, $event)" @mouseup='mouseup(site, $event)'>
    {{ site.name }}
   </div>
 </div>
</div>
<div class="ctn ctn2">
 <div class="sub sub2" v-for="(site, index) in list2">
   <div class="dragCtn">
    {{ index }} : {{ site.name }}
   </div>
 </div> 
</div> 
</div>
<script>
new Vue({
 el: '#app',
 data: {
 list1: [{name:'拖动我', index:0}],
 list2: [{name:'a', index:0}, {name:'b', index:1}, {name:'c', index: 2}, {name:'d', index: 3}],
 vm:'',
 sb_bkx: 0,
 sb_bky: 0,
 },
 methods: {
  mousedown: function (site, event) {
  var event=event||window.event;
  var _target = event.target
  var startx=event.clientX;
  var starty=event.clientY;
  var sb_bkx=startx-event.target.offsetLeft;
  var sb_bky=starty-event.target.offsetTop;
  var ww=document.documentElement.clientWidth;
  var wh = window.innerHeight;
  if (event.preventDefault) {
   event.preventDefault();
  } else{
   event.returnValue=false;
  };
  document.onmousemove=function (ev) {
   var event=ev||window.event;
   var scrolltop=document.documentElement.scrollTop||document.body.scrollTop;
   if (event.clientY < 0 || event.clientX < 0 || event.clientY > wh || event.clientX > ww) {
    return false;
   };
   var endx=event.clientX-sb_bkx;
   var endy=event.clientY-sb_bky;
   _target.style.left=endx+'px';
   _target.style.top=endy+'px';
  }
  },
  mouseup: function (e) {
  document.onmousemove=null;
  }
 }
})
</script>
<style>
 .ctn{
  line-height: 50px;
  cursor: pointer;
  font-size: 20px;
  text-align: center;
  float: left;
 }
 .sub:hover{
  background: #e6dcdc;
  color: white;
  width: 100px;
 }
  .ctn1{
   border: 1px solid green;
   width: 100px;
  }
  .ctn2{
   border: 1px solid black;
   width: 100px;
   margin-left: 50px;
  }
  .fixed{
  width: 100px;
   height: 100px;
  position: fixed;
  background: red;
  left: 10px;
  top: 15px;
  cursor: move;
  }
</style>
</body>
</html>

补充:vue 自定义指令-拖拽

主要思想: 获取拖拽的dom元素,在oDiv.onmousedown事件内获取鼠标相对dom元素本身的位置:

var disX=ev.clientX-oDiv.offsetLeft;
 var disY=ev.clientY-oDiv.offsetTop;

再通过document.onmousemove事件计算dom元素左上角相对 视口的距离:

var l=ev.clientX-disX;
var t=ev.clientY-disY;
oDiv.style.left=l+'px';
oDiv.style.top=t+'px';

完整代码:

<script>
  /* vue-自定义指令-拖拽 */
  Vue.directive('drag',function(){
   var oDiv=this.el;
   oDiv.onmousedown=function(ev){
    var disX=ev.clientX-oDiv.offsetLeft;
    var disY=ev.clientY-oDiv.offsetTop;
    document.onmousemove=function(ev){
     var l=ev.clientX-disX;
     var t=ev.clientY-disY;
     oDiv.style.left=l+'px';
     oDiv.style.top=t+'px';
    };
    document.onmouseup=function(){
     document.onmousemove=null;
     document.onmouseup=null;
    };
   };
  });
  window.onload=function(){
   var vm=new Vue({
    el:'#box',
    data:{
     msg:'welcome'
    }
   });
  };
 </script>
</head>
<body>
 <div id="box">
  <div v-drag :style="{width:'100px', height:'100px', background:'blue', position:'absolute', right:0, top:0}"></div>
  <div v-drag :style="{width:'100px', height:'100px', background:'red', position:'absolute', left:0, top:0}"></div>
 </div>
</body>

总结

以上所述是小编给大家介绍的vue+mousemove实现鼠标拖动功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
js计数器代码
Nov 04 Javascript
js面向对象 多种创建对象方法小结
May 21 Javascript
javascipt:filter过滤介绍及使用
Sep 10 Javascript
jquery实现图片水平滚动效果代码分享
Aug 26 Javascript
浏览器复制插件zeroclipboard使用指南
Mar 26 Javascript
jQuery的ajax和遍历数组json实例代码
Aug 01 Javascript
vue2.0 中#$emit,$on的使用详解
Jun 07 Javascript
angularjs下拉框空白的解决办法
Jun 20 Javascript
bootstrap-table实现服务器分页的示例 (spring 后台)
Sep 01 Javascript
Vue.js组件实现选项卡以及切换特效
Jul 24 Javascript
JS中数组实现代码(倒序遍历数组,数组连接字符串)
Dec 29 Javascript
JavaScript中CreateTextFile函数
Aug 30 Javascript
对vue2.0中.vue文件页面跳转之.$router.push的用法详解
Aug 24 #Javascript
微信小程序Getuserinfo解决方案图解
Aug 24 #Javascript
解决vue2.0路由跳转未匹配相应用路由避免出现空白页面的问题
Aug 24 #Javascript
JavaScript中join()、splice()、slice()和split()函数用法示例
Aug 24 #Javascript
vue 中引用gojs绘制E-R图的方法示例
Aug 24 #Javascript
解决webpack dev-server不能匹配post请求的问题
Aug 24 #Javascript
vue2中,根据list的id进入对应的详情页并修改title方法
Aug 24 #Javascript
You might like
PHP利用Socket获取网站的SSL证书与公钥
2017/06/18 PHP
PHP实现本地图片转base64格式并上传
2020/05/29 PHP
PHP序列化和反序列化深度剖析实例讲解
2020/12/29 PHP
Google Map API更新实现用户自定义标注坐标
2009/07/29 Javascript
EasySlider 基于jQuery功能强大简单易用的滑动门插件
2010/06/11 Javascript
jquery结合html实现中英文页面切换
2016/11/29 Javascript
Javascript 链式作用域详细介绍
2017/02/23 Javascript
JQuery 获取多个select标签option的text内容(实例)
2017/09/07 jQuery
Angular数据绑定机制原理
2018/04/17 Javascript
vue router 用户登陆功能的实例代码
2019/04/24 Javascript
JavaScript中BOM对象原理与用法分析
2019/07/09 Javascript
vue实现pdf文档在线预览功能
2019/11/26 Javascript
一文读懂vue动态属性数据绑定(v-bind指令)
2020/07/20 Javascript
javascript前端和后台进行数据交互方法示例
2020/08/07 Javascript
Vue项目中使用mock.js的完整步骤
2021/01/12 Vue.js
[02:20]DOTA2英雄基础教程 黑暗贤者
2013/12/19 DOTA
python实现360皮肤按钮控件示例
2014/02/21 Python
Linux下使用python调用top命令获得CPU利用率
2015/03/10 Python
使用python将图片按标签分入不同文件夹的方法
2018/12/08 Python
Python3利用Dlib实现摄像头实时人脸检测和平铺显示示例
2019/02/21 Python
Django外键(ForeignKey)操作以及related_name的作用详解
2019/07/29 Python
Python队列RabbitMQ 使用方法实例记录
2019/08/05 Python
python 回溯法模板详解
2020/02/26 Python
你应该知道的30个css选择器
2014/03/19 HTML / CSS
size?爱尔兰官方网站:英国伦敦的球鞋精品店
2019/03/31 全球购物
什么是用户模式(User Mode)与内核模式(Kernel Mode) ?
2015/09/07 面试题
会计专业毕业生自我评价
2013/09/25 职场文书
优秀学生自我鉴定范例
2013/12/18 职场文书
证券期货行业个人的自我评价
2013/12/26 职场文书
工作疏忽检讨书
2014/01/25 职场文书
婚纱摄影师求职信范文
2014/04/17 职场文书
公司活动总结范文
2014/07/01 职场文书
物业管理专业自荐信
2014/07/01 职场文书
员工安全生产责任书
2014/07/22 职场文书
力克胡哲观后感
2015/06/10 职场文书
勤俭节约主题班会
2015/08/13 职场文书