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 相关文章推荐
用window.location.href实现刷新另个框架页面
Mar 07 Javascript
jQuery 源码分析笔记(4) Ready函数
Jun 02 Javascript
基于jQuery实现左右div自适应高度完全相同的代码
Aug 09 Javascript
jQuery获取浏览器中的分辨率实现代码
Apr 23 Javascript
javascript数组去重的六种方法汇总
Aug 16 Javascript
基于JS如何实现类似QQ好友头像hover时显示资料卡的效果(推荐)
Jun 09 Javascript
微信小程序开发之麦克风动画 帧动画 放大 淡出
Apr 18 Javascript
详解JS中的attribute属性
Apr 25 Javascript
用纯Node.JS弹出Windows系统消息提示框实例(MessageBox)
May 17 Javascript
jQuery动画_动力节点节点Java学院整理
Jul 04 jQuery
jQuery实现模糊查询的方法分析
May 10 jQuery
一文快速了解JQuery中的AJAX
May 31 jQuery
理解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使用imagick模块实现图片缩放、裁剪、压缩示例
2014/04/17 PHP
PHP5.5和之前的版本empty函数的不同之处
2014/06/13 PHP
PHP分页类集锦
2014/11/18 PHP
php链表用法实例分析
2015/07/09 PHP
XHProf报告字段含义的解析
2016/05/17 PHP
根据key删除数组中指定的元素实现方法
2017/03/02 PHP
Laravel网站打开速度优化的方法汇总
2017/07/16 PHP
jValidate 基于jQuery的表单验证插件
2009/12/12 Javascript
jquery全选/全不选/反选另一种实现方法(配合原生js)
2013/04/07 Javascript
jquery链式操作的正确使用方法
2014/01/06 Javascript
JavaScript中具名函数的多种调用方式总结
2014/11/08 Javascript
浅谈EasyUI中Treegrid节点的删除
2015/03/01 Javascript
jquery实现键盘左右翻页特效
2015/04/30 Javascript
Jquery实现select multiple左右添加和删除功能的简单实例
2016/05/26 Javascript
手机端 HTML5使用photoswipe.js仿微信朋友圈图片放大效果
2016/08/25 Javascript
详解JavaScript模块化开发
2016/12/04 Javascript
谈谈JavaScript中浏览器兼容问题的写法小议
2016/12/17 Javascript
Javascript实现的StopWatch功能示例
2017/06/13 Javascript
引入JavaScript时alert弹出框显示中文乱码问题
2017/09/16 Javascript
layui实现左侧菜单点击右侧内容区显示
2019/07/26 Javascript
vue resource发送请求的几种方式
2019/09/30 Javascript
JavaScript设计模式之观察者模式与发布订阅模式详解
2020/05/07 Javascript
vue3.0实现插件封装
2020/12/14 Vue.js
Python实现的弹球小游戏示例
2017/08/01 Python
Python中%是什么意思?python中百分号如何使用?
2018/03/20 Python
Python 3.6 -win64环境安装PIL模块的教程
2019/06/20 Python
Python numpy.zero() 初始化矩阵实例
2019/11/27 Python
Python实现子类调用父类的初始化实例
2020/03/12 Python
JBL澳大利亚官方商店:扬声器、耳机和音响系统
2018/05/24 全球购物
医生自荐信
2013/10/11 职场文书
《小石潭记》教学反思
2014/02/13 职场文书
销售人员职业生涯规划范文
2014/03/01 职场文书
2015年毕业生实习评语
2015/03/25 职场文书
党员干部学法用法心得体会
2016/01/21 职场文书
MySQL 主从复制数据不一致的解决方法
2022/03/18 MySQL
基于Python编写简易版的天天跑酷游戏的示例代码
2022/03/23 Python