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全局变量封装模块实现代码
Nov 28 Javascript
JS实现下拉框的动态添加(附效果)
Apr 03 Javascript
JavaScript图片轮播代码分享
Jul 31 Javascript
JS组件Bootstrap实现弹出框效果代码
Apr 26 Javascript
vue.js入门教程之基础语法小结
Sep 01 Javascript
angular+webpack2实战例子
May 23 Javascript
js HTML5 canvas绘制图片的方法
Sep 08 Javascript
Express下采用bcryptjs进行密码加密的方法
Feb 07 Javascript
基于vue循环列表时点击跳转页面的方法
Aug 31 Javascript
基于canvas实现手写签名(vue)
May 21 Javascript
js实现贪吃蛇小游戏(加墙)
Jul 31 Javascript
vue 实现基础组件的自动化全局注册
Dec 25 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读取javascript设置的cookies的代码
2010/04/12 PHP
Notice: Undefined index: page in E:\PHP\test.php on line 14
2010/11/02 PHP
php输出echo、print、print_r、printf、sprintf、var_dump的区别比较
2013/06/21 PHP
ThinkPHP查询中的魔术方法简述
2014/06/25 PHP
php读取torrent种子文件内容的方法(测试可用)
2016/05/03 PHP
PHP基于ICU扩展intl快速实现汉字转拼音及按拼音首字母分组排序的方法
2017/05/03 PHP
PHP实现生成模糊图片的方法示例
2017/12/21 PHP
thinkphp5 框架结合plupload实现图片批量上传功能示例
2020/04/04 PHP
Jquery弹出窗口插件 LeanModal的使用方法
2012/03/10 Javascript
js控制的回到页面顶端goTop的代码实现
2013/03/20 Javascript
AspNet中使用JQuery上传插件Uploadify详解
2015/05/20 Javascript
JavaScript实现图片轮播的方法
2015/07/31 Javascript
JS正则表达式比较常见用法
2016/01/26 Javascript
浅谈JS继承_借用构造函数 &amp; 组合式继承
2016/08/16 Javascript
BootStrap中
2016/12/10 Javascript
JS生成一维码(条形码)功能示例
2017/01/19 Javascript
js实现本地图片文件拖拽效果
2017/07/18 Javascript
vue弹窗组件的实现示例代码
2018/09/10 Javascript
解决vue项目axios每次请求session不一致的问题
2020/10/24 Javascript
举例讲解Python中的死锁、可重入锁和互斥锁
2015/11/05 Python
OpenCV 边缘检测
2019/07/10 Python
利用python实现汉字转拼音的2种方法
2019/08/12 Python
详解python百行有效代码实现汉诺塔小游戏(简约版)
2020/10/30 Python
Timberland美国官网:全球领先的户外品牌
2016/08/15 全球购物
荷兰最大的儿童服装店:The Kids Republic
2019/04/13 全球购物
Conforama瑞士:家具、厨房、电器、装饰
2020/09/06 全球购物
声明struct x1 { . . . }; 和typedef struct { . . . }x2;有什么不同
2012/06/02 面试题
英文简历自荐信范文
2013/12/11 职场文书
电子商务个人自荐信
2013/12/12 职场文书
致铅球运动员广播稿精选
2014/01/12 职场文书
生物制药自我鉴定
2014/01/25 职场文书
工会主席岗位责任制
2014/02/11 职场文书
《将心比心》教学反思
2014/04/08 职场文书
汽车服务工程专业自荐信
2014/09/02 职场文书
大学生党性分析材料
2014/12/19 职场文书
宾馆卫生管理制度
2015/08/06 职场文书