纯JS实现可拖拽表单的简单实例


Posted in Javascript onSeptember 02, 2016

因为要用到可拖拽表单,个人要比较喜欢自己动手,不怎么喜欢在不懂实现或者原理的情况下用插件,所以查找资料实现了一个。

思路:放入:用mousedown判断鼠标点击的位置是否在触发控件的位置,如果是,mousemove的时候clone一个控件,修改透明度,然后放入容器内的时候remove这个控件,并且在容器内生成一个放入的控件(放入的控件和触发的控件可以不一样)

拖拽:同样的, mousedown的时候判断是哪个控件,mousemove的时候需要放一个占位div放在原有的位置上,并将元素修改透明度然后设置为绝对定位方便拖动,在进行拖动的时候,占位div也会跟着鼠标位置进行改变(判断当前鼠标位置是否是容器内控件的左上角加上控件高度的一半),放下的时候进行判断占位div的位置进行插入。具体看代码吧,这个思路加上的时间距离代码实现的时间有点久远了,所有可能不是很准确,但是大概的思路就是这样了。

ps:要用到拖拽表单功能的,基本上可能都会要更改以往设计数据库方式,这里可以提供给你们一个搜索关键词 表的纵向存储

注释基本上都已经写的很详细了,直接上代码吧。

有什么问题请大神们多多指教

<!DOCTYPE html>
<html>
  <head>
    <title>Test</title>
    <style type="text/css" >
      html,body
      {
        height:100%;
        width:100%;
        padding:0;
        margin:0;
      }
      .dialog
      {
       /*  width:250px;
        height:250px;*/
        position:absolute;
        background-color:#ccc;
        -webkit-box-shadow:1px 1px 3px #292929;
        -moz-box-shadow:1px 1px 3px #292929;
        box-shadow:1px 1px 3px #292929;
        /*margin:10px;*/
        top:50px;
        left: 50px;
        opacity:1;
      }
      .dialog-title
      {
        color:#fff;
        background-color:#404040;
        font-size:12pt;
        font-weight:bold;
        padding:4px 6px;
        cursor:move;
        position:absolute;
        top:50px;
        left: 50px;
      }
      
      .dialog-content
      {
        padding:4px;
        cursor:move;
      }
      .none{
        display: none;
      }
      .box{
        width: 200px;
        height: 500px;
        background-color: gray;
        line-height: 30px;
        margin: 100px;
      }
      .place{
        width: 200px;
        height: 50px;
        border: 1px dashed red;
      }
    </style>
    <script type="text/javascript" src="js/devWin.js"></script>
  </head>
  <body>
    <!-- <div id="dlgTest" class="dialog"> -->
      <div id = "title" class="dialog-title">Dialog</div>
      <div id = "title2" class="dialog-title" style ="top:10px">Dialog</div>
    <!-- </div> -->
    <a id = "a" href="#">123</a>
    <input id = "text" type="text" class = "none">
    <div id = "box" class = "box">
    <!-- <input type="" name="" placeholder=""> -->
    </div>
    <div class = "place"></div>
  </body>
  <script type="text/javascript">
    //要传入的变量
    //点击触发的对象 
    var click = document.getElementById("title");
    var click2 = document.getElementById("title2");
    //放入的容器
    var box = document.getElementById("box");
    //容器内占位的DIV
    var place = document.createElement("div");
    place.className = "place";
    //往容器内添加的对象
    var create = document.createElement("input");
    create.type = "text";
    var create2 = document.createElement("input");
    create2.type = "password";
    //是否可以添加多个
    var isMany = true;
    createWin(click,create,isMany,place,box);
    createWin(click2,create2,isMany,place,box);
  </script>
</html>
/**
* author:lzh 
* 作用:可拖拽排序表单实现
* 参数:oclick   点击触发事件的对象
*   ocreate  出发后在表单中传入的对象
*   bisMany  单个oclick对象是否可拖入多个ocreate对象
*   oplace   拖入时占位div对象
*   obox    拖入的容器,不填则默认为body
*/
function createWin(oclick,ocreate,bisMany,oplace,obox=document.body)
{
  //是否点击了触发对象
  var isClick = false;
  //触发对象是否为容器内的元素
  var isIncludeBox = false;
  oplace.style.width = obox.offsetWidth-5 + "px";
  oplace.style.height = oclick.offsetHeight-5 + "px";
  //移动效果的临时元素
  var oclickClone;
  var oclickDown;
  //计算偏移量
  var diffObj;
  var diffX;
  var diffY;
  var tmp;
  var omove_position;
  //点是否包含在容器内
  function isInclude(x,y,includeBox=obox)
  {
    if(x > includeBox.offsetLeft 
    && y > includeBox.offsetTop 
    && x < includeBox.offsetLeft + includeBox.offsetWidth
    && y < includeBox.offsetTop + includeBox.offsetHeight)
      return true;
    return false;
  }
  //移动效果函数
  function moveMagic(omove,e)
  {
    // omove_position = window.getComputedStyle(omove).getPropertyValue('position');
    omove.style.opacity = 0.4;
    omove.style.position = "absolute";
    document.body.appendChild(omove);
    omove.style.left = e.clientX-diffX+"px";
    omove.style.top = e.clientY-diffY+"px";
  }
  function getdiff(e)
  {
    diffObj = e.target;
    diffX = e.clientX-diffObj.offsetLeft;
    diffY = e.clientY-diffObj.offsetTop;
  }
  //鼠标按下事件
  function down(e)
  {
    if(isInclude(e.clientX,e.clientY,oclick))
    {
      isClick = true;
      //克隆点击的触发节点
      oclickClone=oclick.cloneNode(true);
      //计算鼠标的偏移量(如果有margin的话会有偏移现象)
      getdiff(e);
    }
    else
    {
      getdiff(e);
      var child = obox.childNodes;
      for(var i=0; i < child.length; i++)
      {
        //判断鼠标点击是否是容器内的元素,并且不能是占位div(如果不加这个占位div判断会有bug,具体原因不知道)
        if(isInclude(e.clientX,e.clientY,child[i])&& child[i] != oplace)
        {
          isClick = true;
          isIncludeBox = true;
          //克隆元素用来拖动时的效果
          oclickClone = child[i].cloneNode(true);
          //克隆元素用来放下
          oclickDown = child[i].cloneNode(true);
          //按下之后删除元素,并使用移动效果来展示元素
          obox.removeChild(child[i]);
          moveMagic(oclickClone,e);
          //插入占位div来弄
          obox.insertBefore(oplace,child[i]);
          // flag = true;
          break;
        }
      }
    }
  }
  //鼠标移动事件
  function move(e)
  {
    if(isClick)
    {
      moveMagic(oclickClone,e);
      //判断鼠标是否移动到了容器内部
      if(isInclude(e.clientX,e.clientY,obox))
      {
        //计算容器内的子节点
        var child = obox.childNodes;
        //一旦进入就可以在首位置插入占位DIV
        obox.insertBefore(oplace,child[0]);
        //根据鼠标位置放置占位DIV
        for(var i = 0; i < child.length; i++)
        {
          //因为占位DIV是唯一的,所以只需要这样判断即可
          if(e.clientY > child[i].offsetTop+child[i].offsetHeight/2)
          {
            //判断是否拖动到了结尾
            if(i != child.length-1)
              obox.insertBefore(oplace,child[i+1]);
            else
              obox.appendChild(oplace);
          }
        }
      }
    }
  }
  //鼠标抬起事件
  function up(e)
  {
    isClick = false;
    //鼠标抬起则可以删除临时的拖动效果元素
    document.body.removeChild(oclickClone);
    //如果将元素放置到了容器内
    if(isInclude(e.clientX,e.clientY))
    {
      var child = obox.childNodes;
      //占位div的位置
      var insertPlace;
      for(var i=0; i<child.length;i++)
      {
        //确定占位div的位置
        if(oplace === child[i])
        {
          obox.removeChild(child[i]);
          insertPlace = i;
          break;
        }
      }
      //判断是否可以放置多个
      if(!bisMany)
      {
        if(isIncludeBox)
          ocreate = oclickDown;
        if(insertPlace==child.length)
          obox.appendChild(ocreate);
        else
          obox.insertBefore(ocreate,child[insertPlace]);
      }
      else
      {
          //可以放置多个则需要每个都克隆一下
        if(isIncludeBox)
          var ocreateClone = oclickDown;
        else
          var ocreateClone = ocreate.cloneNode(true);
        if(insertPlace==child.length)
          obox.appendChild(ocreateClone);
        else
        {
          obox.insertBefore(ocreateClone,child[insertPlace]);
        }
      }
    }
    else
    {
      if(isIncludeBox)
      {
        var child = obox.childNodes;
        for(var i=0; i<child.length; i++)
        {
          if(child[i] === oplace)
          {
            obox.removeChild(child[i]);
            obox.insertBefore(oclickDown,child[i]);
          }1
        }
      }
    }
    isIncludeBox = false;
  }
  document.addEventListener('mousemove',move);
  document.addEventListener('mousedown',down);
  document.addEventListener('mouseup',up);
}

以上这篇纯JS实现可拖拽表单的简单实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JS实现自动切换文字的导航效果代码
Aug 27 Javascript
三种AngularJS中获取数据源的方式
Feb 02 Javascript
Angularjs 制作购物车功能实例代码
Sep 14 Javascript
如何选择适合你的JavaScript框架
Nov 20 Javascript
react配合antd组件实现的管理系统示例代码
Apr 24 Javascript
JavaScript设计模式之构造器模式(生成器模式)定义与用法实例分析
Jul 26 Javascript
vue.js编译时给生成的文件增加版本号
Sep 17 Javascript
vue axios 简单封装以及思考
Oct 09 Javascript
jquery实现购物车基本功能
Oct 25 jQuery
jQuery实现轮播图效果demo
Jan 11 jQuery
js实现拖拽元素选择和删除
Aug 25 Javascript
vuex页面刷新导致数据丢失的解决方案
Dec 10 Vue.js
vue.js入门教程之绑定class和style样式
Sep 02 #Javascript
js绘制购物车抛物线动画
Nov 18 #Javascript
基于jQuery实现发送短信验证码后的倒计时功能(无视页面关闭)
Sep 02 #Javascript
基于JS实现发送短信验证码后的倒计时功能(无视页面刷新,页面关闭不进行倒计时功能)
Sep 02 #Javascript
node.js中module.exports与exports用法上的区别
Sep 02 #Javascript
AngularJs Scope详解及示例代码
Sep 01 #Javascript
AngularJs Modules详解及示例代码
Sep 01 #Javascript
You might like
关于PHP结束标签的使用细节探讨及联想
2013/03/04 PHP
基于PHP文件操作的详细诠释
2013/06/21 PHP
ThinkPHP使用心得分享-上传类UploadFile的使用
2014/05/15 PHP
PHP生成短网址的3种方法代码实例
2014/07/08 PHP
PHP截取指定图片大小的方法
2014/12/10 PHP
PHP连接MSSQL时nvarchar字段长度被截断为255的解决方法
2014/12/25 PHP
php实现数据库的增删改查
2017/02/26 PHP
不用写JS也能使用EXTJS视频演示
2008/12/29 Javascript
js 居中漂浮广告
2010/03/21 Javascript
JavaScript中判断原生函数检查function是否是原生代码
2014/09/09 Javascript
jquery.form.js实现将form提交转为ajax方式提交的方法
2015/04/07 Javascript
JavaScript时间操作之年月日星期级联操作
2016/01/15 Javascript
javascript添加前置0(补零)的几种方法
2017/01/05 Javascript
详解如何将angular-ui的图片轮播组件封装成一个指令
2017/05/09 Javascript
vue 实现数字滚动增加效果的实例代码
2018/07/06 Javascript
利用soaplib搭建webservice详细步骤和实例代码
2013/11/20 Python
在Python中实现贪婪排名算法的教程
2015/04/17 Python
Python实现读取Properties配置文件的方法
2018/03/29 Python
python取余运算符知识点详解
2019/06/27 Python
python 使用装饰器并记录log的示例代码
2019/07/12 Python
python模拟鼠标点击和键盘输入的操作
2019/08/04 Python
Pytorch 使用不同版本的cuda的方法步骤
2020/04/02 Python
神经网络训练采用gpu设置的方式
2021/03/03 Python
css3 中的新特性加强记忆详解
2016/04/16 HTML / CSS
CSS3 不定高宽垂直水平居中的几种方式
2020/03/26 HTML / CSS
HTML5 Canvas阴影使用方法实例演示
2013/08/02 HTML / CSS
Zavvi美国:英国娱乐之家
2017/03/19 全球购物
系统管理员的职责包括那些?管理的对象是什么?
2016/09/20 面试题
大学生求职信范文应怎么写
2014/01/01 职场文书
美术专业个人自我评价
2014/01/18 职场文书
建设投标担保书
2014/05/13 职场文书
市政工程技术专业自荐书
2014/07/06 职场文书
检察院院长群众路线教育实践活动个人整改措施
2014/10/04 职场文书
《花钟》教学反思
2016/02/17 职场文书
话题作文之诚信
2019/11/28 职场文书
mysql查找连续出现n次以上的数字
2022/05/11 MySQL