原生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 相关文章推荐
仿服务器端脚本方式的JS模板实现方法
Apr 27 Javascript
js弹出层(jQuery插件形式附带reLoad功能)
Apr 12 Javascript
从零学JSON之JSON数据结构
May 19 Javascript
9款2014最热门jQuery实用特效推荐
Dec 07 Javascript
在JavaScript的jQuery库中操作AJAX的方法讲解
Aug 15 Javascript
给before和after伪元素设置js效果的方法
Dec 04 Javascript
Sortable.js拖拽排序使用方法解析
Nov 04 Javascript
jquery二级目录选中当前页的css样式
Dec 08 Javascript
swiper插件自定义切换箭头按钮
Dec 28 Javascript
vue判断input输入内容全是空格的方法
Mar 02 Javascript
详解nuxt路由鉴权(express模板)
Nov 21 Javascript
微信小程序实现通过js操作wxml的wxss属性示例
Dec 06 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求数组全排列,元素所有组合的方法
2016/05/05 PHP
PHP处理CSV表格文件的常用操作方法总结
2016/07/01 PHP
php实现有序数组打印或排序的方法【附Python、C及Go语言实现代码】
2016/11/10 PHP
php实现往pdf中加数字签名操作示例【附源码下载】
2018/08/07 PHP
详解PHP多个进程配合redis的有序集合实现大文件去重
2019/03/06 PHP
jquery利用ajax调用后台方法实例
2013/08/23 Javascript
js语法学习之判断一个对象是否为数组
2014/05/13 Javascript
JS实现表单中checkbox对勾选中增加边框显示效果
2015/08/21 Javascript
通过js获取上传的图片信息(临时保存路径,名称,大小)然后通过ajax传递给后端的方法
2015/10/01 Javascript
jquery实现右侧栏菜单选择操作
2016/03/04 Javascript
JavaScript中Number对象的toFixed() 方法详解
2016/09/02 Javascript
JS填写银行卡号每隔4位数字加一个空格
2016/12/19 Javascript
JavaScript监听手机物理返回键的两种解决方法
2017/08/14 Javascript
jQuery Ajax向服务端传递数组参数值的实例代码
2017/09/03 jQuery
vue.js2.0点击获取自己的属性和jquery方法
2018/02/23 jQuery
angular 内存溢出的问题解决
2018/07/12 Javascript
详解几十行代码实现一个vue的状态管理
2019/01/28 Javascript
关于JavaScript 数组你应该知道的事情(推荐)
2019/04/10 Javascript
Vue自定义全局Toast和Loading的实例详解
2019/04/18 Javascript
python正则过滤字母、中文、数字及特殊字符方法详解
2020/02/11 Python
TensorFlow的reshape操作 tf.reshape的实现
2020/04/19 Python
python实现登录与注册系统
2020/11/30 Python
HTML5实现无刷新修改URL的方法
2019/11/14 HTML / CSS
HTML5开发动态音频图的实现
2020/07/02 HTML / CSS
Groupon比利时官方网站:特卖和网上购物高达-70%
2019/08/09 全球购物
const和static readonly区别
2013/05/20 面试题
爱我中华教学反思
2014/04/28 职场文书
小学校本培训方案
2014/06/06 职场文书
学术会议通知
2015/04/15 职场文书
2015年语文教学工作总结
2015/05/25 职场文书
成绩单家长意见
2015/06/03 职场文书
高中物理教学反思
2016/02/19 职场文书
离婚协议书范本(2016最新版)
2016/03/18 职场文书
妇联2016年六一国际儿童节活动总结
2016/04/06 职场文书
Nginx反向代理多个服务器的实现方法
2021/03/31 Servers
php 获取音视频时长,PHP 利用getid3 获取音频文件时长等数据
2021/04/01 PHP