原生js实现拖拽功能基本思路详解


Posted in Javascript onApril 18, 2018

如果要设置物体拖拽,那么必须使用三个事件,并且这三个事件的使用顺序不能颠倒。

1.onmousedown:鼠标按下事件
2.onmousemove:鼠标移动事件
3.onmouseup:鼠标抬起事件

  拖拽的基本原理就是根据鼠标的移动来移动被拖拽的元素。鼠标的移动也就是x、y坐标的变化;元素的移动就是style.position的 top和left的改变。当然,并不是任何时候移动鼠标都要造成元素的移动,而应该判断鼠标左键的状态是否为按下状态,是否是在可拖拽的元素上按下的。

基本思路如下:

拖拽状态 = 0鼠标在元素上按下的时候{   
  拖拽状态 = 1   
  记录下鼠标的x和y坐标   
  记录下元素的x和y坐标   
  }  
 鼠标在元素上移动的时候{   
  如果拖拽状态是0就什么也不做。   
  如果拖拽状态是1,那么   
  元素y = 现在鼠标y - 原来鼠标y + 原来元素y   
  元素x = 现在鼠标x - 原来鼠标x + 原来元素x   
  }    
 鼠标在任何时候放开的时候{   
  拖拽状态 = 0   
}

部分实例代码:

HTML部分

<div class="calculator" id="drag">**********</div>

CSS部分

calculator { 
  position: absolute; /*设置绝对定位,脱离文档流,便于拖拽*/ 
  display: block; 
  width: 218px; 
  height: 280px; 
  cursor: move;  /*鼠标呈拖拽状*/ 
}

JS部分

window.onload = function() { 
  //拖拽功能(主要是触发三个事件:onmousedown\onmousemove\onmouseup) 
  var drag = document.getElementById('drag'); 
  //点击某物体时,用drag对象即可,move和up是全局区域,也就是整个文档通用,应该使用document对象而不是drag对象(否则,采用drag对象时物体只能往右方或下方移动) 
  drag.onmousedown = function(e) { 
    var e = e || window.event; //兼容ie浏览器 
    var diffX = e.clientX - drag.offsetLeft; //鼠标点击物体那一刻相对于物体左侧边框的距离=点击时的位置相对于浏览器最左边的距离-物体左边框相对于浏览器最左边的距离 
    var diffY = e.clientY - drag.offsetTop; 
    /*低版本ie bug:物体被拖出浏览器可是窗口外部时,还会出现滚动条, 
      解决方法是采用ie浏览器独有的2个方法setCapture()\releaseCapture(),这两个方法, 
      可以让鼠标滑动到浏览器外部也可以捕获到事件,而我们的bug就是当鼠标移出浏览器的时候, 
      限制超过的功能就失效了。用这个方法,即可解决这个问题。注:这两个方法用于onmousedown和onmouseup中*/ 
      if(typeof drag.setCapture!='undefined'){ 
        drag.setCapture(); 
      } 
    document.onmousemove = function(e) { 
      var e = e || window.event; //兼容ie浏览器 
      var left=e.clientX-diffX; 
      var top=e.clientY-diffY; 
      //控制拖拽物体的范围只能在浏览器视窗内,不允许出现滚动条 
      if(left<0){ 
        left=0; 
      }else if(left >window.innerWidth-drag.offsetWidth){ 
        left = window.innerWidth-drag.offsetWidth; 
      } 
      if(top<0){ 
        top=0; 
      }else if(top >window.innerHeight-drag.offsetHeight){ 
        top = window.innerHeight-drag.offsetHeight; 
      } 
      //移动时重新得到物体的距离,解决拖动时出现晃动的现象 
      drag.style.left = left+ 'px'; 
      drag.style.top = top + 'px'; 
    }; 
    document.onmouseup = function(e) { //当鼠标弹起来的时候不再移动 
      this.onmousemove = null; 
      this.onmouseup = null; //预防鼠标弹起来后还会循环(即预防鼠标放上去的时候还会移动) 
      //修复低版本ie bug 
      if(typeof drag.releaseCapture!='undefined'){ 
        drag.releaseCapture(); 
      } 
    }; 
  }; 
};

总结

以上所述是小编给大家介绍的原生js实现拖拽功能基本思路详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
UpdatePanel和Jquery冲突的解决方法
Apr 01 Javascript
jQuery插件编写步骤详解
Jun 03 Javascript
JavaScript实现移动端滑动选择日期功能
Jun 21 Javascript
JS中如何实现复选框全选功能
Dec 19 Javascript
详解javascript常用工具类的封装
Jan 30 Javascript
jQuery实现模糊查询的方法分析
May 10 jQuery
Vue中使用 setTimeout() setInterval()函数的问题
Sep 13 Javascript
JavaScript创建对象的四种常用模式实例分析
Jan 11 Javascript
iphone刘海屏页面适配方法
May 07 Javascript
vue实现的封装全局filter并统一管理操作示例
Feb 02 Javascript
vue.js click点击事件获取当前元素对象的操作
Aug 07 Javascript
vue+elementUI 实现内容区域高度自适应的示例
Sep 26 Javascript
一个基于react的图片裁剪组件示例
Apr 18 #Javascript
JS实现对json对象排序并删除id相同项功能示例
Apr 18 #Javascript
Angular ng-animate和ng-cookies用法详解
Apr 18 #Javascript
JS实现的base64加密解密操作示例
Apr 18 #Javascript
JS实现简单获取最近7天和最近3天日期的方法
Apr 18 #Javascript
详解Node使用Puppeteer完成一次复杂的爬虫
Apr 18 #Javascript
jQuery滚动条美化插件nicescroll简单用法示例
Apr 18 #jQuery
You might like
php 强制下载文件实现代码
2013/10/28 PHP
php生成xml时添加CDATA标签的方法
2014/10/17 PHP
php页面,mysql数据库转utf-8乱码,utf-8编码问题总结
2015/08/27 PHP
PHP常用设计模式之委托设计模式
2016/02/13 PHP
Javascript基础教程之break和continue语句
2015/01/18 Javascript
JavaScript中神奇的call()方法
2015/03/12 Javascript
jQuery选择器源码解读(二):select方法
2015/03/31 Javascript
node.js实现端口转发
2016/04/14 Javascript
jQuery操作iframe中js函数的方法小结
2016/07/06 Javascript
EasyUI的doCellTip实现鼠标放到单元格上提示单元格内容
2016/08/24 Javascript
基于Node.js + WebSocket打造即时聊天程序嗨聊
2016/11/29 Javascript
Angular-Touch库用法示例
2016/12/22 Javascript
微信小程序 slider 详解及实例代码
2017/01/10 Javascript
使用bat打开多个cmd窗口执行gulp、node
2017/02/17 Javascript
微信小程序 es6-promise.js封装请求与处理异步进程
2017/06/12 Javascript
手把手教你用Node.js爬虫爬取网站数据的方法
2018/07/05 Javascript
vue+axios 前端实现登录拦截的两种方式(路由拦截、http拦截)
2018/10/24 Javascript
Vuex的actions属性的具体使用
2019/04/14 Javascript
vue移动端城市三级联动组件使用详解
2019/07/26 Javascript
Element Dialog对话框的使用示例
2020/07/26 Javascript
Vue 防止短时间内连续点击后多次触发请求的操作
2020/11/11 Javascript
Python3访问并下载网页内容的方法
2015/07/28 Python
web.py 十分钟创建简易博客实现代码
2016/04/22 Python
Python判断文件或文件夹是否存在的三种方法
2017/07/27 Python
PyQt5实现类似别踩白块游戏
2019/01/24 Python
Django框架登录加上验证码校验实现验证功能示例
2019/05/23 Python
PyQt5图形界面播放音乐的实例
2019/06/17 Python
python数据抓取3种方法总结
2021/02/07 Python
关于PySnooper 永远不要使用print进行调试的问题
2021/03/04 Python
努比亚手机官网:nubia
2016/10/06 全球购物
佳能英国官方网站:Canon UK
2017/08/08 全球购物
Java中有几种方法可以实现一个线程?用什么关键字修饰同步方法?stop()和suspend()方法为何不推荐使用?
2015/08/04 面试题
如何查询Oracle数据库中已经创建的索引
2013/10/11 面试题
后勤岗位职责
2013/11/26 职场文书
督导岗位职责
2015/02/04 职场文书
使用Springboot实现健身房管理系统
2021/07/01 Java/Android