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 相关文章推荐
最新28个很棒的jQuery 教程
May 28 Javascript
js给dropdownlist添加选项的小例子
Mar 04 Javascript
jQuery内置的AJAX功能和JSON的使用实例
Jul 27 Javascript
jquery实现动态画圆
Dec 04 Javascript
JavaScript检查数字是否为整数或浮点数的方法
Jun 09 Javascript
javascript动态添加checkbox复选框的方法
Dec 23 Javascript
DropDownList控件绑定数据源的三种方法
Dec 24 Javascript
EsLint入门学习教程
Feb 17 Javascript
微信小程序里引入SVG矢量图标的方法
Sep 20 Javascript
layui table 复选框跳页后再回来保持原来选中的状态示例
Oct 26 Javascript
Openlayers实现地图全屏显示
Sep 28 Javascript
vue项目多环境配置(.env)的实现
Jul 21 Vue.js
对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
在PHP3中实现SESSION的功能(二)
2006/10/09 PHP
PHP insert语法详解
2008/06/07 PHP
php中$this-&amp;gt;含义分析
2009/11/29 PHP
PHP url的pathinfo模式加载不同控制器的简单实现
2016/08/12 PHP
PHP脚本自动识别验证码查询汽车违章
2016/12/20 PHP
微信开发之获取JSAPI TICKET
2017/07/07 PHP
js模拟弹出效果代码修正版
2008/08/07 Javascript
通过判断JavaScript的版本实现执行不同的代码
2010/05/11 Javascript
jQuery实现平滑滚动的标签分栏切换效果
2015/08/28 Javascript
jQueryUI中的datepicker使用方法详解
2016/05/25 Javascript
JS比较两个数值的大小实例
2016/11/25 Javascript
Nodejs中使用phantom将html转为pdf或图片格式的方法
2017/09/18 NodeJs
jquery实现倒计时小应用
2017/09/19 jQuery
JavaScript实现带有子菜单和控件的slider轮播图效果
2017/11/01 Javascript
vue使用element-ui的el-input监听不了回车事件的解决方法
2018/01/12 Javascript
Python中的模块导入和读取键盘输入的方法
2015/10/16 Python
Python基于正则表达式实现检查文件内容的方法【文件检索】
2017/08/30 Python
python实现批量修改图片格式和尺寸
2018/06/07 Python
python调用百度语音REST API
2018/08/30 Python
python合并已经存在的sheet数据到新sheet的方法
2018/12/11 Python
Python3实现打印任意宽度的菱形代码
2020/04/12 Python
Keras中的多分类损失函数用法categorical_crossentropy
2020/06/11 Python
Html5无刷新修改browser Url的方法
2014/01/15 HTML / CSS
英国高级百货公司:Harvey Nichols
2017/01/29 全球购物
煤矿班组长岗位职责
2013/12/29 职场文书
家长给老师的道歉信
2014/01/13 职场文书
秋季校运动会广播稿
2014/02/23 职场文书
借款协议书范本
2014/04/22 职场文书
实习评语大全
2014/04/26 职场文书
搞笑爱情保证书
2014/04/29 职场文书
派出所正风肃纪剖析材料
2014/10/10 职场文书
物业接待员岗位职责
2015/04/15 职场文书
毕业生政审意见范文
2015/06/04 职场文书
python 如何将两个实数矩阵合并为一个复数矩阵
2021/05/19 Python
口袋妖怪冰系十大最强精灵,几何雪花排第七,第六类似北极熊
2022/03/18 日漫
golang实现浏览器导出excel文件功能
2022/03/25 Golang