JS拖拽组件学习使用


Posted in Javascript onJanuary 19, 2016

JS代码需要常写,不然容易生疏,最近虽然一直在看JS的原型,行为委托等知识点,但是动手写代码的量略有减少。本文与大家分享一个拖拽组件,供大家参考,具体内容如下

首先,看一下拖拽的原理。

JS拖拽组件学习使用

被拖拽元素位置的变化,left值的变化其实就是鼠标位置水平方向的变化值,e.clientX - 鼠标左键按下时e.clientX。
top值的变化其实就是鼠标位置竖直方向的变化值,e.clientY - 鼠标左键按下时e.clientY。
另外就是设置拖拽的范围,上下左右不得超过父元素所在的区域。

function Drag (config){
      this.moveTarget = document.getElementById(config.id);
      if(config.parentId){
        this.targetParent = document.getElementById(config.parentId);
        this.max_left = this.targetParent.clientWidth - this.moveTarget.offsetWidth;
        this.max_top = this.targetParent.clientHeight - this.moveTarget.offsetHeight;
      }else{
        console.log(document.documentElement.clientHeight + "||" + this.moveTarget.offsetHeight)
        this.max_left = document.documentElement.clientWidth - this.moveTarget.offsetWidth - 
          parseInt(this.getStyle(document.body, "border-width"));
        this.max_top = document.documentElement.clientHeight - this.moveTarget.offsetHeight- 
          parseInt(this.getStyle(document.body, "border-width"));
      }      
      this.lock = true;
    }
    Drag.prototype.getStyle = function(element, attr){
      if(element.currentStyle){
        return element.currentStyle[attr];
      }else{
        return window.getComputedStyle(element,null).getPropertyValue(attr)
      }
    }
    Drag.prototype.moDown = function(e){
      e = e || window.event;
      this.clientX = e.clientX;
      this.clientY = e.clientY;
      //鼠标按下时,drag的left值,top值(写在style中或者是css中)
      this.startLeft = parseInt(this.moveTarget.style.left || this.getStyle(this.moveTarget, "left"));
      this.startTop = parseInt(this.moveTarget.style.top || this.getStyle(this.moveTarget, "top"));
      //鼠标按下时,鼠标的clientX值,clientY值
      this.startClientX = e.clientX;
      this.startClientY = e.clientY;
      this.lock = false;
    };
    Drag.prototype.moMove = function(e){
      e = e || window.event;
      if(e.which != 1){
        this.lock = true;
      }
      if(!this.lock){
        var realLeft = this.startLeft + e.clientX - this.startClientX;//实际的移动范围
        var realTop = this.startTop + e.clientY - this.startClientY;
          //rightLeft , rightTop; //left, top 取值(在可移动范围内)
        var rightLeft = realLeft > this.max_left ? this.max_left : ( realLeft > 0 ? realLeft : 0 );
        var rightTop = realTop > this.max_top ? this.max_top : ( realTop > 0 ? realTop : 0 );
        this.moveTarget.style.left = rightLeft + "px";
        this.moveTarget.style.top = rightTop + "px";
      }
    };
    Drag.prototype.moUp = function(e){
      e = e || window.event;
      this.lock = true;
    };
    Drag.prototype.startDrag = function(){
      console.log(this)
      this.moveTarget.onmousedown = function(e){this.moDown(e)}.bind(this);
      this.moveTarget.onmousemove = function(e){this.moMove(e)}.bind(this);
      this.moveTarget.onmouseup = function(e){this.moUp(e)}.bind(this);
    }

说明:moDown响应鼠标左键按下操作,moMove响应鼠标移动操作,MoUp响应鼠标抬起操作。

在moMove中增加了e.which判断,e.which ==1 表示鼠标左键按下,这是为了解决,鼠标移除可拖拽范围外,再移回时,无需按下左键,被拖拽元素就会跟着动的Bug。

使用说明:

在使用时,被拖拽元素的id是必须参数,父元素的id(即可以拖拽移动的范围)为可选参数,如果不传递父元素的id,则默认使用documentElement为可拖拽的范围。

如果传递父元素,请别忘了将父元素的定位设为position:relative或position:absolute。

在使用时,先引入拖拽插件的js文件。

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="Generator" content="EditPlus®">
    <meta name="Author" content="刘艳">
    <meta name="Keywords" content="关键字">
    <meta name="Description" content="描述">
    <title>Document</title>
    <style>
      *{
        margin:0px;
        padding:0px;
      }
      #content{
        width:600px;
        height:500px;
        position:relative;
        border:5px solid green;
      }
      #drag{
        position:absolute;
        height:100px;
        width:100px;
        top:50px;left:0px;
        background:pink;
        cursor:pointer;
      }
    </style>
  </head>
  <body>
    <div id = "content">
      <div id = "drag" >
      </div> 
    </div>
  </body>
</html>
<script src = "url/drag.js"></script>
<script>
  window.onload = function(){
    var drag = new Drag({id: "drag", parentId: "content"});
    drag.startDrag();

  }

</script>

如果您想在整个窗口中拖拽,请不要设置被拖拽元素的父元素的定位,即,使其相对body定位。

如果您需要对body定位,但是又需要设置其父元素的position为非static,那么您可以对本插件进行扩展。

希望本文对大家学习javascript程序设计有所帮助。

Javascript 相关文章推荐
JavaScript的public、private和privileged模式
Dec 28 Javascript
解决JS浮点数运算出现Bug的方法
Mar 12 Javascript
Javascript拓展String方法小结
Jul 08 Javascript
javascript使用call调用微信API
Dec 15 Javascript
js实现感应鼠标图片透明度变化的方法
Feb 20 Javascript
详解vue.js全局组件和局部组件
Apr 10 Javascript
前端跨域的几种解决方式总结(推荐)
Aug 16 Javascript
200行代码实现blockchain 区块链实例详解
Mar 14 Javascript
Vue.js特性Scoped Slots的浅析
Feb 20 Javascript
node.js命令行教程图文详解
May 27 Javascript
浅谈layer的Icon样式以及一些常用的layer窗口使用方法
Sep 11 Javascript
使用vuex-persistedstate本地存储vuex
Apr 29 Vue.js
理解JS绑定事件
Jan 19 #Javascript
AngularJS模块学习之Anchor Scroll
Jan 19 #Javascript
jQuery unbind()方法实例详解
Jan 19 #Javascript
jQuery绑定事件监听bind和移除事件监听unbind用法实例详解
Jan 19 #Javascript
详解JavaScript对象序列化
Jan 19 #Javascript
学习JavaScript设计模式之单例模式
Jan 19 #Javascript
jQuery中bind(),live(),delegate(),on()绑定事件方法实例详解
Jan 19 #Javascript
You might like
php下几个常用的去空、分组、调试数组函数
2009/02/22 PHP
ThinkPHP5+Layui实现图片上传加预览功能
2018/08/17 PHP
Smarty模板类内部原理实例分析
2019/07/03 PHP
Smarty模板配置实例简析
2019/07/20 PHP
基于jquery的tab切换 js原理
2010/04/01 Javascript
javascript instanceof 内部机制探析
2010/10/15 Javascript
IE6下focus与blur错乱的解决方案
2011/07/31 Javascript
jQuery中after的两种用法实例
2013/07/03 Javascript
使用 TypeScript 重新编写的 JavaScript 坦克大战游戏代码
2015/04/07 Javascript
Java中Timer的用法详解
2015/10/21 Javascript
用canvas 实现个图片三角化(LOW POLY)效果
2016/02/18 Javascript
JavaScript修改作用域外变量的方法
2016/03/25 Javascript
vue如何实现observer和watcher源码解析
2017/03/09 Javascript
Node.JS文件系统解析实例详解
2017/05/15 Javascript
vue注册组件的几种方式总结
2018/03/08 Javascript
Vue入门之animate过渡动画效果
2018/04/08 Javascript
vue router+vuex实现首页登录验证判断逻辑
2018/05/17 Javascript
微信小程序如何自定义table组件
2019/06/29 Javascript
基于Vue的商品主图放大镜方案详解
2019/09/19 Javascript
详解js location.href和window.open的几种用法和区别
2019/12/02 Javascript
ssm+vue前后端分离框架整合实现(附源码)
2020/07/08 Javascript
ant design的table组件实现全选功能以及自定义分页
2020/11/17 Javascript
[04:54]DOTA2 2017国际邀请赛:上届冠军WINGS采访短片
2017/08/09 DOTA
用python删除java文件头上版权信息的方法
2014/07/31 Python
Python随机数用法实例详解【基于random模块】
2017/04/18 Python
Python编程实现线性回归和批量梯度下降法代码实例
2018/01/04 Python
Python基于matplotlib画箱体图检验异常值操作示例【附xls数据文件下载】
2019/01/07 Python
深入浅析Python 中 is 语法带来的误解
2019/05/07 Python
python经典趣味24点游戏程序设计
2019/07/26 Python
python 类的继承 实例方法.静态方法.类方法的代码解析
2019/08/23 Python
python PIL模块的基本使用
2020/09/29 Python
美国知名户外用品畅销中心:Sierra Trading Post
2016/07/19 全球购物
一名毕业生的自我鉴定
2013/12/04 职场文书
辞职信标准格式
2015/02/27 职场文书
浅谈Redis在直播场景的实践方案
2021/04/27 Redis
Python实现8种常用抽样方法
2021/06/27 Python