浅析JavaScript动画模拟拖拽原理


Posted in Javascript onDecember 09, 2016

模拟拖拽的原理:

浅析JavaScript动画模拟拖拽原理

x1等于div.offsetLeft

y1等于div.offsetTop

x2等于ev.clientX(ev表示event事件)

y2等于ev.clientY

当我们在方块上按下鼠标的时候,x2-x1即可确定。移动鼠标之后,我们用鼠标当前的位置即x4、y4减去x2-x1、y2-y1就可以得到方块现在的位置。

代码:

<!DOCTYPE html>
 <html lang="en">
 <head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
   #box{
    width: 100px;
    height: 100px;
    background: red;
   position: absolute;
   }
  </style>
 </head>
 <body>  
  <div id="box"></div>
  <script type="text/javascript">
  var oBox = document.getElementById('box');
  oBox.onmousedown = function(ev){
  // 鼠标按下 
  var ev = ev || event; 
  // 获取鼠标离div得距离
  var mouseBoxleft = ev.clientX - this.offsetLeft;
  var mouseBoxTop = ev.clientY - this.offsetTop; 
  oBox.onmousemove = function(ev){
   // 鼠标按下左键并移动 
  var ev = ev || event; 
   // 设置div移动时,它的位置
   oBox.style.left = ev.clientX - mouseBoxleft + 'px';
   oBox.style.top = ev.clientY - mouseBoxleft + 'px';
   }
   oBox.onmouseup = function(){
   // 鼠标左键抬起 
   oBox.onmousemove = oBox.onmouseup = null;
   }
  }
  </script>
 </body>
 </html>

优化代码:

【1】鼠标移动快的时候,鼠标会移出方块,这时方块就不会再跟随鼠标动了。

解决办法:就是将onmousemove和onmouseup加到document对象上

代码:

<!DOCTYPE html>
 <html lang="en">
 <head>
  <meta charset="UTF-8">
 <title>Document</title>
  <style>
   #box{
   width: 100px;
    height: 100px;
   background: red;
    position: absolute;
   }
  </style>
 </head>
 <body>  
  <div id="box"></div>
  <script>
 var oBox = document.getElementById('box'); 
 oBox.onmousedown = function(ev){
  // 鼠标按下 
  var ev = ev || event; 
  // 获取鼠标离div得距离
  var mouseBoxleft = ev.clientX - this.offsetLeft;
  var mouseBoxTop = ev.clientY - this.offsetTop; 
  document.onmousemove = function(ev){
  // 鼠标按下左键并移动  
   var ev = ev || event; 
   // 设置div移动时,它的位置
   oBox.style.left = ev.clientX - mouseBoxleft + 'px';
   oBox.style.top = ev.clientY - mouseBoxleft + 'px'; 
   } 
   document.onmouseup = function(){
   // 鼠标左键抬起  
   document.onmousemove = document.onmouseup = null;
   }
  }
  </script>
 </body>
 </html>

【2】当要拖动的方块中有文字时会触发浏览器的默认行为

 解决办法:1、使用return false添加到onmousedown事件中阻止浏览器的默认行为(IE除外)

2、使用全局捕获(IE)

1、使用return false添加到onmousedown事件中阻止浏览器的默认行为(IE除外)

代码:

<!DOCTYPE html>
 <html lang="en">
 <head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
   #box{
    width: 100px;
    height: 100px;
    background: red;
    position: absolute;
    top: 0;
    left: 0;
  }
 </style>
 </head>
 <body>  
  <div id="box">模拟拖拽</div>
  <script>
 var oBox = document.getElementById('box');
 oBox.onmousedown = function(ev){
   // 鼠标按下
   var ev = ev || event;
   // 获取鼠标离div得距离
   var mouseBoxleft = ev.clientX - this.offsetLeft;
   var mouseBoxTop = ev.clientY - this.offsetTop;
   document.onmousemove = function(ev){
   // 鼠标按下左键并移动 
    var ev = ev || event;
    // 设置div移动时,它的位置
    oBox.style.left = ev.clientX - mouseBoxleft + 'px';
    oBox.style.top = ev.clientY - mouseBoxleft + 'px';
   }
   document.onmouseup = function(){
  // 鼠标左键抬起 
   document.onmousemove = document.onmouseup = null;
  }
   // 阻止默认行为
   return false;
  }
  </script>
 </body>
 </html>

2、使用全局捕获(IE)

 全局捕获:当我们给一个元素这只全局捕获后,改元素会监听后续发生的所有事件,当有事件发生的时候就会触发改元素的事件

代码:

<!DOCTYPE html>
 <html lang="en">
 <head>
  <meta charset="UTF-8">
  <title>Document</title>
 </head>
 <body>
  <input type="button" id="button1" value="弹出1" />
  <input type="button" id="button2" value="弹出2" />
  <script type="text/javascript">
  window.onload = function(){
  var Btn1 = document.getElementById('button1');
   var Btn2 = document.getElementById('button2'); 
   Btn1.setCapture(); 
   Btn1.onclick = function(){
    alert(1);
  }
   Btn2.onclick = function(){
   alert(2);
  }
 }
 </script>
 </body>
</html>

给Btn1设置了全局捕获之后,即使我们点击了Btn2还是会触发Btn1的点击事件

在模拟拖拽中,给要拖拽的方块onmousedown添加全局捕获然后再onmouseup中取消全局捕获

代码:

<!DOCTYPE html>
 <html lang="en">
 <head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
  #box{
    width: 100px;
    height: 100px;
    background: red;
    position: absolute;
  }
  </style>
</head>
 <body>  
  <div id="box">模拟拖拽</div>
  <script>
 var oBox = document.getElementById('box');
  oBox.onmousedown = function(ev){
  // 鼠标按下 
   var ev = ev || event;
  // 获取鼠标离div得距离
   var mouseBoxleft = ev.clientX - this.offsetLeft;
   var mouseBoxTop = ev.clientY - this.offsetTop;
   // IE浏览器,全局捕获
   if(oBox.setCapture){
   oBox.setCapture();
   }
   document.onmousemove = function(ev){
  // 鼠标按下左键并移动 
    var ev = ev || event;
    // 设置div移动时,它的位置
    oBox.style.left = ev.clientX - mouseBoxleft + 'px';
    oBox.style.top = ev.clientY - mouseBoxleft + 'px';
   }
   document.onmouseup = function(){
   // 鼠标左键抬起 
    document.onmousemove = document.onmouseup = null;
    //IE下,释放全局捕获 releaseCapture();
   if ( oBox.releaseCapture ) {
     oBox.releaseCapture();
    }
   }
   // 阻止默认行为
   return false;
  }
  </script>
 </body>
 </html>

【3】封装模拟拖拽函数

 代码:

<!DOCTYPE html>
 <html lang="en">
 <head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style>
   #box{
    width: 100px;
    height: 100px;
    background: red;
    position: absolute;
   }
  </style>
 </head>
 <body>
  <div id="box">模拟拖拽</div>
  <script>
  var oBox = document.getElementById('box');
  drag(oBox);
  function drag(obj){
   obj.onmousedown = function(ev){
    // 鼠标按下
   var ev = ev || event;
    // 获取鼠标离div得距离
    var mouseBoxleft = ev.clientX - this.offsetLeft;
    var mouseBoxTop = ev.clientY - this.offsetTop;
    // IE浏览器,全局捕获
    if(obj.setCapture){
     obj.setCapture();
    }
    document.onmousemove = function(ev){
    // 鼠标按下左键并移动 
     var ev = ev || event;
     // 设置div移动时,它的位置
     obj.style.left = ev.clientX - mouseBoxleft + 'px';
     obj.style.top = ev.clientY - mouseBoxleft + 'px';
    }
    document.onmouseup = function(){
    // 鼠标左键抬起 
     document.onmousemove = document.onmouseup = null;
    //IE下,释放全局捕获 releaseCapture();
     if ( obj.releaseCapture ) {
      obj.releaseCapture();
    }
    }
    // 阻止默认行为
    return false;
  }
 }
  </script>
 </body>
</html>

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
js实现iframe动态调整高度的代码
Jan 06 Javascript
javascript小数计算出现近似值的解决办法
Feb 06 Javascript
一个挺有意思的Javascript小问题说明
Sep 26 Javascript
字符串的replace方法应用浅析
Dec 06 Javascript
JS小功能(button选择颜色)简单实例
Nov 29 Javascript
从零学习node.js之express入门(六)
Feb 25 Javascript
利用jQuery实现一个简单的表格上下翻页效果
Mar 14 Javascript
利用vue.js实现被选中状态的改变方法
Feb 08 Javascript
全面了解JavaScript的作用域链
Apr 03 Javascript
vue 百度地图(vue-baidu-map)绘制方向箭头折线实例代码详解
Apr 28 Javascript
解决echarts echarts数据动态更新和dataZoom被重置问题
Jul 20 Javascript
vue监听滚动事件的方法
Dec 21 Vue.js
JS定时器实现数值从0到10来回变化
Dec 09 #Javascript
原生js实现查询天气小应用
Dec 09 #Javascript
JS实现太极旋转思路分析
Dec 09 #Javascript
学习使用bootstrap的modal和carousel
Dec 09 #Javascript
PHP+jquery+ajax实现分页
Dec 09 #Javascript
javascript垃圾收集机制的原理分析
Dec 08 #Javascript
基于JS实现的随机数字抽签实例
Dec 08 #Javascript
You might like
mysql_fetch_assoc和mysql_fetch_row的功能加起来就是mysql_fetch_array
2007/01/15 PHP
PHP 实现explort() 功能的详解
2013/06/20 PHP
WampServer下安装多个版本的PHP、mysql、apache图文教程
2015/01/07 PHP
PHP Include文件实例讲解
2019/02/15 PHP
innerText和innerHTML 一些问题分析
2009/05/18 Javascript
JS 控件事件小结
2012/10/31 Javascript
javascript向后台传送相同属性的参数即数组参数
2014/02/17 Javascript
js实现类似MSN提示的页面效果代码分享
2015/08/24 Javascript
jquery对象和DOM对象的任意相互转换
2016/02/21 Javascript
JavaScript简单实现弹出拖拽窗口(一)
2016/06/17 Javascript
解决同一页面中两个iframe互相调用jquery,js函数的方法
2016/12/12 Javascript
微信小程序 Tab页切换更新数据
2017/01/05 Javascript
jQuery中的on与bind绑定事件区别实例详解
2017/02/28 Javascript
three.js中文文档学习之通过模块导入
2017/11/20 Javascript
jQuery实现定时隐藏对话框的方法分析
2018/02/12 jQuery
vue pages 多入口项目 + chainWebpack 全局引用缩写说明
2020/09/21 Javascript
JavaScript中展开运算符及应用的实例代码
2021/01/14 Javascript
python 调用win32pai 操作cmd的方法
2017/05/28 Python
详解Python在七牛云平台的应用(一)
2017/12/05 Python
python3处理含有中文的url方法
2018/05/10 Python
Python随机函数库random的使用方法详解
2019/08/21 Python
解决Python3用PIL的ImageFont输出中文乱码的问题
2019/08/22 Python
Tensorflow中的dropout的使用方法
2020/03/13 Python
python中watchdog文件监控与检测上传功能
2020/10/30 Python
html5指南-6.如何创建离线web应用程序实现离线访问
2013/01/07 HTML / CSS
实例讲解使用SVG制作loading加载动画的方法
2016/04/05 HTML / CSS
约瑟夫·特纳男装:Joseph Turner
2017/10/10 全球购物
世界排名第一的万圣节服装店:Spirit Halloween
2018/10/16 全球购物
瑞士隐形眼镜和护理产品网上商店:Linsenklick
2019/10/21 全球购物
新加坡最早生产电动滑板车的制造商之一:FunsToTheFore
2020/09/08 全球购物
生产部厂长职位说明书
2014/03/03 职场文书
我的中国梦演讲稿500字
2014/08/19 职场文书
师德师风个人自我剖析材料
2014/09/27 职场文书
小学教师求职信范文
2015/03/20 职场文书
小兵张嘎观后感
2015/06/03 职场文书
python中使用redis用法详解
2022/12/24 Redis