纯JS实现可拖拽表单
转载注明出处!!!
转载注明出处!!!
转载注明出处!!!
因为要用到可拖拽表单,个人要比较喜欢自己动手,不怎么喜欢在不懂实现或者原理的情况下用插件,所以查找资料实现了一个。
思路:放入:用mousedown判断鼠标点击的位置是否在触发控件的位置,如果是,mousemove的时候clone一个控件,修改透明度,然后放入容器内的时候remove这个控件,并且在容器内生成一个放入的控件(放入的控件和触发的控件可以不一样)
拖拽:同样的, mousedown的时候判断是哪个控件,mousemove的时候需要放一个占位div放在原有的位置上,并将元素修改透明度然后设置为绝对定位方便拖动,在进行拖动的时候,占位div也会跟着鼠标位置进行改变(判断当前鼠标位置是否是容器内控件的左上角加上控件高度的一半),放下的时候进行判断占位div的位置进行插入。具体看代码吧,这个思路加上的时间距离代码实现的时间有点久远了,所有可能不是很准确,但是大概的思路就是这样了。
ps:要用到拖拽表单功能的,基本上可能都会要更改以往设计数据库方式,这里可以提供给你们一个搜索关键词 表的纵向存储
注释基本上都已经写的很详细了,直接上代码吧。
有什么问题请大神们多多指教
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title>Test</title> 5 <style type="text/css" > 6 html,body 7 { 8 height:100%; 9 width:100%; 10 padding:0; 11 margin:0; 12 } 13 .dialog 14 { 15 /* width:250px; 16 height:250px;*/ 17 position:absolute; 18 background-color:#ccc; 19 -webkit-box-shadow:1px 1px 3px #292929; 20 -moz-box-shadow:1px 1px 3px #292929; 21 box-shadow:1px 1px 3px #292929; 22 /*margin:10px;*/ 23 top:50px; 24 left: 50px; 25 opacity:1; 26 } 27 .dialog-title 28 { 29 color:#fff; 30 background-color:#404040; 31 font-size:12pt; 32 font-weight:bold; 33 padding:4px 6px; 34 cursor:move; 35 position:absolute; 36 top:50px; 37 left: 50px; 38 } 39 40 .dialog-content 41 { 42 padding:4px; 43 cursor:move; 44 } 45 .none{ 46 display: none; 47 } 48 .box{ 49 width: 200px; 50 height: 500px; 51 background-color: gray; 52 line-height: 30px; 53 margin: 100px; 54 } 55 .place{ 56 width: 200px; 57 height: 50px; 58 border: 1px dashed red; 59 } 60 </style> 61 <script type="text/javascript" src="js/devWin.js"></script> 62 </head> 63 <body> 64 <!-- <div id="dlgTest" class="dialog"> --> 65 <div id = "title" class="dialog-title">Dialog</div> 66 <div id = "title2" class="dialog-title" style ="top:10px">Dialog</div> 67 <!-- </div> --> 68 <a id = "a" href="#">123</a> 69 <input id = "text" type="text" class = "none"> 70 <div id = "box" class = "box"> 71 <!-- <input type="" name="" placeholder=""> --> 72 </div> 73 <div class = "place"></div> 74 </body> 75 <script type="text/javascript"> 76 //要传入的变量 77 //点击触发的对象 78 var click = document.getElementById("title"); 79 var click2 = document.getElementById("title2"); 80 //放入的容器 81 var box = document.getElementById("box"); 82 //容器内占位的DIV 83 var place = document.createElement("div"); 84 place.className = "place"; 85 //往容器内添加的对象 86 var create = document.createElement("input"); 87 create.type = "text"; 88 var create2 = document.createElement("input"); 89 create2.type = "password"; 90 //是否可以添加多个 91 var isMany = true; 92 createWin(click,create,isMany,place,box); 93 createWin(click2,create2,isMany,place,box); 94 </script> 95 </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /** 2 * author:lzh 3 * 作用:可拖拽排序表单实现 4 * 参数:oclick 点击触发事件的对象 5 * ocreate 出发后在表单中传入的对象 6 * bisMany 单个oclick对象是否可拖入多个ocreate对象 7 * oplace 拖入时占位div对象 8 * obox 拖入的容器,不填则默认为body 9 */ 10 function createWin(oclick,ocreate,bisMany,oplace,obox=document.body) 11 { 12 //是否点击了触发对象 13 var isClick = false; 14 //触发对象是否为容器内的元素 15 var isIncludeBox = false; 16 oplace.style.width = obox.offsetWidth-5 + "px"; 17 oplace.style.height = oclick.offsetHeight-5 + "px"; 18 //移动效果的临时元素 19 var oclickClone; 20 var oclickDown; 21 //计算偏移量 22 var diffObj; 23 var diffX; 24 var diffY; 25 var tmp; 26 var omove_position; 27 //点是否包含在容器内 28 function isInclude(x,y,includeBox=obox) 29 { 30 if(x > includeBox.offsetLeft 31 && y > includeBox.offsetTop 32 && x < includeBox.offsetLeft + includeBox.offsetWidth 33 && y < includeBox.offsetTop + includeBox.offsetHeight) 34 return true; 35 return false; 36 } 37 //移动效果函数 38 function moveMagic(omove,e) 39 { 40 // omove_position = window.getComputedStyle(omove).getPropertyValue('position'); 41 omove.style.opacity = 0.4; 42 omove.style.position = "absolute"; 43 document.body.appendChild(omove); 44 omove.style.left = e.clientX-diffX+"px"; 45 omove.style.top = e.clientY-diffY+"px"; 46 } 47 function getdiff(e) 48 { 49 diffObj = e.target; 50 diffX = e.clientX-diffObj.offsetLeft; 51 diffY = e.clientY-diffObj.offsetTop; 52 } 53 //鼠标按下事件 54 function down(e) 55 { 56 if(isInclude(e.clientX,e.clientY,oclick)) 57 { 58 isClick = true; 59 //克隆点击的触发节点 60 oclickClone=oclick.cloneNode(true); 61 //计算鼠标的偏移量(如果有margin的话会有偏移现象) 62 getdiff(e); 63 } 64 else 65 { 66 getdiff(e); 67 var child = obox.childNodes; 68 for(var i=0; i < child.length; i++) 69 { 70 //判断鼠标点击是否是容器内的元素,并且不能是占位div(如果不加这个占位div判断会有bug,具体原因不知道) 71 if(isInclude(e.clientX,e.clientY,child[i])&& child[i] != oplace) 72 { 73 isClick = true; 74 isIncludeBox = true; 75 //克隆元素用来拖动时的效果 76 oclickClone = child[i].cloneNode(true); 77 //克隆元素用来放下 78 oclickDown = child[i].cloneNode(true); 79 //按下之后删除元素,并使用移动效果来展示元素 80 obox.removeChild(child[i]); 81 moveMagic(oclickClone,e); 82 //插入占位div来弄 83 obox.insertBefore(oplace,child[i]); 84 // flag = true; 85 break; 86 } 87 } 88 } 89 } 90 //鼠标移动事件 91 function move(e) 92 { 93 if(isClick) 94 { 95 moveMagic(oclickClone,e); 96 //判断鼠标是否移动到了容器内部 97 if(isInclude(e.clientX,e.clientY,obox)) 98 { 99 //计算容器内的子节点 100 var child = obox.childNodes; 101 //一旦进入就可以在首位置插入占位DIV 102 obox.insertBefore(oplace,child[0]); 103 //根据鼠标位置放置占位DIV 104 for(var i = 0; i < child.length; i++) 105 { 106 //因为占位DIV是唯一的,所以只需要这样判断即可 107 if(e.clientY > child[i].offsetTop+child[i].offsetHeight/2) 108 { 109 //判断是否拖动到了结尾 110 if(i != child.length-1) 111 obox.insertBefore(oplace,child[i+1]); 112 else 113 obox.appendChild(oplace); 114 } 115 } 116 } 117 } 118 } 119 //鼠标抬起事件 120 function up(e) 121 { 122 isClick = false; 123 //鼠标抬起则可以删除临时的拖动效果元素 124 document.body.removeChild(oclickClone); 125 //如果将元素放置到了容器内 126 if(isInclude(e.clientX,e.clientY)) 127 { 128 var child = obox.childNodes; 129 //占位div的位置 130 var insertPlace; 131 for(var i=0; i<child.length;i++) 132 { 133 //确定占位div的位置 134 if(oplace === child[i]) 135 { 136 obox.removeChild(child[i]); 137 insertPlace = i; 138 break; 139 } 140 } 141 //判断是否可以放置多个 142 if(!bisMany) 143 { 144 if(isIncludeBox) 145 ocreate = oclickDown; 146 if(insertPlace==child.length) 147 obox.appendChild(ocreate); 148 else 149 obox.insertBefore(ocreate,child[insertPlace]); 150 } 151 else 152 { 153 //可以放置多个则需要每个都克隆一下 154 if(isIncludeBox) 155 var ocreateClone = oclickDown; 156 else 157 var ocreateClone = ocreate.cloneNode(true); 158 if(insertPlace==child.length) 159 obox.appendChild(ocreateClone); 160 else 161 { 162 obox.insertBefore(ocreateClone,child[insertPlace]); 163 } 164 } 165 } 166 else 167 { 168 if(isIncludeBox) 169 { 170 var child = obox.childNodes; 171 for(var i=0; i<child.length; i++) 172 { 173 if(child[i] === oplace) 174 { 175 obox.removeChild(child[i]); 176 obox.insertBefore(oclickDown,child[i]); 177 }1 178 } 179 } 180 } 181 isIncludeBox = false; 182 } 183 document.addEventListener('mousemove',move); 184 document.addEventListener('mousedown',down); 185 document.addEventListener('mouseup',up); 186 }