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入门·动态的时钟,显示完整的一些方法,新年倒计时
Oct 01 Javascript
JS中图片缓冲loading技术的实例代码
Aug 29 Javascript
javascript 处理null及null值示例
Jun 09 Javascript
JavaScript设置获取和设置属性的方法
Mar 04 Javascript
javascript使用avalon绑定实现checkbox全选
May 06 Javascript
尝试动手制作javascript放大镜效果
Dec 25 Javascript
jQuery过滤选择器用法示例
Sep 12 Javascript
mui back 返回刷新页面的实例
Dec 06 Javascript
详解用JS添加和删除class类名
Mar 25 Javascript
vscode中eslint插件的配置(prettier配置无效)
Sep 10 Javascript
ElementUI多个子组件表单的校验管理实现
Nov 07 Javascript
详解 javascript对象创建模式
Oct 30 Javascript
理解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 过滤危险html代码
2009/06/29 PHP
PHP中数组的分组排序实例
2014/06/01 PHP
PHP学习记录之数组函数
2018/06/01 PHP
php跨域调用json的例子
2013/11/13 Javascript
jQuery实现转动随机数抽奖效果的方法
2015/05/21 Javascript
简介JavaScript中的setHours()方法的使用
2015/06/11 Javascript
实例解析jQuery中proxy()函数的用法
2016/05/24 Javascript
js获取元素的外链样式的简单实现方法
2016/06/06 Javascript
把vue-router和express项目部署到服务器的方法
2018/02/21 Javascript
JavaScript树的深度优先遍历和广度优先遍历算法示例
2018/07/30 Javascript
create-react-app安装出错问题解决方法
2018/09/04 Javascript
koa-router源码学习小结
2018/09/07 Javascript
ES6新增的数组知识实例小结
2020/05/23 Javascript
在GitHub Pages上使用Pelican搭建博客的教程
2015/04/25 Python
Python实现通过文件路径获取文件hash值的方法
2017/04/29 Python
利用selenium 3.7和python3添加cookie模拟登陆的实现
2017/11/20 Python
python学习入门细节知识点
2018/03/29 Python
python实现机器人卡牌
2019/10/06 Python
Python多线程及其基本使用方法实例分析
2019/10/29 Python
python新手学习可变和不可变对象
2020/06/11 Python
HTML5 canvas实现移动端上传头像拖拽裁剪效果
2016/03/14 HTML / CSS
html5视频媒体标签video的使用方法及完整参数说明详解
2019/09/27 HTML / CSS
特罗佩亚包官方网站:Tropea
2017/01/03 全球购物
MCM英国官网:奢侈皮具制品
2017/04/18 全球购物
C++面试题:关于链表和指针
2013/06/05 面试题
什么叫应用程序域?什么是托管代码?什么是强类型系统?什么是装箱和拆箱?什么是重载?CTS、CLS和CLR分别作何解释?
2012/05/23 面试题
小学教师的个人自我鉴定
2013/10/24 职场文书
毕业生自我鉴定
2013/12/04 职场文书
数控技校生自我鉴定
2014/03/02 职场文书
节电标语大全
2014/06/23 职场文书
2014年个人债务授权委托书范本
2014/09/22 职场文书
2014年街道办事处工作总结
2014/12/11 职场文书
2015年实习单位评语
2015/03/25 职场文书
导游词之安徽醉翁亭
2020/01/10 职场文书
python开发实时可视化仪表盘的示例
2021/05/07 Python
MySQL批量更新不同表中的数据
2022/05/11 MySQL