纯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 相关文章推荐
鼠标移动到一张图片时变为另一张图片
Dec 05 Javascript
Display SQL Server Login Mode
Jun 21 Javascript
JQuery中SetTimeOut传参问题探讨
May 10 Javascript
jQuery使用drag效果实现自由拖拽div
Jun 11 Javascript
jquery制做精致的倒计时特效
Jun 13 Javascript
easyui messager alert 三秒后自动关闭提示的实例
Nov 07 Javascript
Bootstrap基本组件学习笔记之下拉菜单(7)
Dec 07 Javascript
轻松学习Javascript闭包
Mar 01 Javascript
常用的js方法合集
Mar 10 Javascript
为Jquery EasyUI 组件加上清除功能的方法(详解)
Apr 13 jQuery
微信小程序实现人脸识别
May 25 Javascript
js实现图片区域可点击大小随意改变(适用移动端)代码实例
Sep 11 Javascript
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 expects parameter 1 to be resource, array given 错误
2011/03/23 PHP
PHP在不同页面间传递Json数据示例代码
2013/06/08 PHP
用Zend Studio+PHPnow+Zend Debugger搭建PHP服务器调试环境步骤
2014/01/19 PHP
PHP把空格、换行符、中文逗号等替换成英文逗号的正则表达式
2014/05/04 PHP
php基本函数汇总
2015/07/09 PHP
php封装的mysqli类完整实例
2016/10/18 PHP
jquery实现表格奇数偶数行不同样式(有图为证及实现代码)
2013/01/23 Javascript
EasyUI中combobox默认值注意事项
2015/03/01 Javascript
IE6-IE9使用JSON、table.innerHTML所引发的问题
2015/12/22 Javascript
JavaScript暂停和继续定时器的实现方法
2016/07/18 Javascript
node.js(express)中使用Jcrop进行图片剪切上传功能
2017/04/21 Javascript
深入探究node之Transform
2017/07/20 Javascript
js使用html2canvas实现屏幕截取的示例代码
2017/08/28 Javascript
jQuery实现经典的网页3D轮播图封装功能【附源码下载】
2019/02/15 jQuery
Vue插件从封装到发布的完整步骤记录
2019/02/28 Javascript
使用mixins实现elementUI表单全局验证的解决方法
2019/04/02 Javascript
ES6新增的数组知识实例小结
2020/05/23 Javascript
原生JS实现音乐播放器
2021/01/26 Javascript
[19:24]DOTA2客户端使用指南 一分钟快速设置轻松超神
2013/09/24 DOTA
合并百度影音的离线数据( with python 2.3)
2015/08/04 Python
详解Python 序列化Serialize 和 反序列化Deserialize
2017/08/20 Python
python生成九宫格图片
2018/11/19 Python
Python Django 命名空间模式的实现
2019/08/09 Python
python 实现检验33品种数据是否是正态分布
2019/12/09 Python
pytorch 准备、训练和测试自己的图片数据的方法
2020/01/10 Python
python3.8与pyinstaller冲突问题的快速解决方法
2020/01/16 Python
tensorflow模型转ncnn的操作方式
2020/05/25 Python
解决Keras 自定义层时遇到版本的问题
2020/06/16 Python
使用HTML和CSS实现的标签云效果(附demo)
2021/02/03 HTML / CSS
Steiff台湾官网:德国金耳釦泰迪熊
2019/12/26 全球购物
售后服务经理岗位职责
2014/02/25 职场文书
房地产端午节活动方案
2014/08/24 职场文书
公司向个人借款协议书范本
2014/10/09 职场文书
卖房协议书样本
2014/10/30 职场文书
小学英语课教学反思
2016/02/15 职场文书
django如何自定义manage.py管理命令
2021/04/27 Python