纯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 jquery获取随机生成id的服务器控件的三种方法
Jul 11 Javascript
Javascript 拖拽雏形(逐行分析代码,让你轻松了拖拽的原理)
Jan 23 Javascript
纯js实现手风琴效果
Apr 17 Javascript
详解Angular的数据显示优化处理
Dec 26 Javascript
JavaScript cookie详解及简单实例应用
Dec 31 Javascript
微信小程序 动态的设置图片的高度和宽度详解及实例代码
Feb 24 Javascript
微信小程序“摇一摇”的实例代码
Jul 20 Javascript
关于vue.js发布后路径引用的问题解决
Aug 15 Javascript
浅谈react性能优化的方法
Sep 05 Javascript
JS对象和字符串之间互换操作实例分析
Feb 02 Javascript
jQuery+Ajax+js实现请求json格式数据并渲染到html页面操作示例
Jun 02 jQuery
解决vue net :ERR_CONNECTION_REFUSED报错问题
Aug 13 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 新手入门教程
2009/08/03 PHP
php实现图片添加描边字和马赛克的方法
2014/12/10 PHP
PHP获取一段文本显示点阵宽度和高度的方法
2015/03/12 PHP
PHP-FPM之Chroot执行环境详解
2015/08/03 PHP
PHP设计模式之单例模式定义与用法分析
2019/03/26 PHP
如何通过PHP实现Des加密算法代码实例
2020/05/09 PHP
利用PHP内置SERVER开启web服务(本地开发使用)
2021/03/09 PHP
js option删除代码集合
2008/11/12 Javascript
分享XmlHttpRequest调用Webservice的一点心得
2012/07/20 Javascript
js delete 用法(删除对象属性及变量)
2014/08/24 Javascript
Shell脚本实现Linux系统和进程资源监控
2015/03/05 Javascript
jQuery跨域问题解决方案
2015/08/03 Javascript
简介EasyUI datagrid editor combogrid搜索框的实现
2016/04/01 Javascript
jQuery通过deferred对象管理ajax异步
2016/05/20 Javascript
bootstrap学习笔记之初识bootstrap
2016/06/21 Javascript
ES6概念 ymbol.for()方法
2016/12/25 Javascript
js仿拉勾网首页穿墙广告效果
2017/03/08 Javascript
JS中Swiper的使用和轮播图效果
2017/08/11 Javascript
AngularJS日程表案例详解
2017/08/15 Javascript
element 结合vue 在表单验证时有值却提示错误的解决办法
2018/01/22 Javascript
详解swipe使用及竖屏页面滚动方法
2018/06/28 Javascript
javascript实现手动点赞效果
2019/04/09 Javascript
解决Angularjs异步操作后台请求用$q.all排列先后顺序问题
2019/11/29 Javascript
使用PYTHON接收多播数据的代码
2012/03/01 Python
tensorflow 加载部分变量的实例讲解
2018/07/27 Python
解决Django连接db遇到的问题
2019/08/29 Python
Python-for循环的内部机制
2020/06/12 Python
父亲生日宴会答谢词
2014/01/10 职场文书
高中物理教学反思
2014/02/08 职场文书
竞选演讲稿范文大全
2014/05/12 职场文书
运动会方队口号
2014/06/07 职场文书
2014年餐厅服务员工作总结
2014/11/18 职场文书
大学生个人学年总结
2015/02/15 职场文书
学校光盘行动倡议书
2015/04/28 职场文书
运动会主持词大全
2015/07/02 职场文书
运动会主持人开幕词
2016/03/04 职场文书