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 相关文章推荐
不一样的文字闪烁 轮番闪烁
Nov 11 Javascript
Javascript图像处理—虚拟边缘介绍及使用方法
Dec 27 Javascript
Bootstrap布局组件教程之Bootstrap下拉菜单
Jun 12 Javascript
基于bootstrap实现广告轮播带图片和文字效果
Jul 22 Javascript
JavaScript利用闭包实现模块化
Jan 13 Javascript
layui表格实现代码
May 20 Javascript
Three.js加载外部模型的教程详解
Nov 10 Javascript
微信小程序用户自定义模版用法实例分析
Nov 28 Javascript
webpack多页面开发实践
Dec 18 Javascript
微信小程序实现城市列表选择
Jun 05 Javascript
基于vue循环列表时点击跳转页面的方法
Aug 31 Javascript
javascript事件循环event loop的简单模型解释与应用分析
Mar 14 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过滤危险html代码的函数
2008/07/22 PHP
PHP上传文件时文件过大$_FILES为空的解决方法
2013/11/26 PHP
ThinkPHP 在阿里云上的nginx.config配置实例详解
2017/10/11 PHP
PHP实现一个按钮点击上传多个图片操作示例
2020/01/23 PHP
打印json对象的内容及JSON.stringify函数应用
2013/03/29 Javascript
js实现两点之间画线的方法
2015/05/12 Javascript
JS重载实现方法分析
2016/12/16 Javascript
three.js实现3D模型展示的示例代码
2017/12/31 Javascript
Node.Js中实现端口重用原理详解
2018/05/03 Javascript
vue封装一个简单的div框选时间的组件的方法
2019/01/06 Javascript
Vue-axios-post数据后端接不到问题解决
2020/01/09 Javascript
微信小程序个人中心的列表控件实现代码
2020/04/26 Javascript
vue中移动端调取本地的复制的文本方式
2020/07/18 Javascript
vue添加自定义右键菜单的完整实例
2020/12/08 Vue.js
[01:05:07]DOTA2-DPC中国联赛 正赛 DLG vs Dragon BO3 第一场2月1日
2021/03/11 DOTA
精确查找PHP WEBSHELL木马的方法(1)
2011/04/12 Python
python处理二进制数据的方法
2015/06/03 Python
python绘制中国大陆人口热力图
2018/11/07 Python
Python Numpy计算各类距离的方法
2019/07/05 Python
wxPython实现整点报时
2019/11/18 Python
python判断变量是否为int、字符串、列表、元组、字典的方法详解
2020/02/13 Python
python修改linux中文件(文件夹)的权限属性操作
2020/03/05 Python
PyQt5实现简单的计算器
2020/05/30 Python
pycharm-professional-2020.1下载与激活的教程
2020/09/21 Python
python中复数的共轭复数知识点总结
2020/12/06 Python
德国游戏机商店:Konsolenkost
2019/12/08 全球购物
财务会计毕业生自荐信
2013/11/02 职场文书
2014年中秋寄语
2014/08/11 职场文书
招标授权委托书样本
2014/09/23 职场文书
领导莅临指导欢迎词
2015/09/30 职场文书
《活见鬼》教学反思
2016/02/24 职场文书
优胜劣汰,强者为王——读《鲁滨逊漂流记》有感
2019/08/15 职场文书
go语言求任意类型切片的长度操作
2021/04/26 Golang
每日六道java新手入门面试题,通往自由的道路
2021/06/30 Java/Android
从QQtabBar看css命名规范BEM的详细介绍
2021/08/07 HTML / CSS
Redis 报错 error:NOAUTH Authentication required
2022/05/15 Redis