純JS實(shí)現(xiàn)可拖拽表單的簡(jiǎn)單實(shí)例
因?yàn)橐玫娇赏献П韱危瑐€(gè)人要比較喜歡自己動(dòng)手,不怎么喜歡在不懂實(shí)現(xiàn)或者原理的情況下用插件,所以查找資料實(shí)現(xiàn)了一個(gè)。
思路:放入:用mousedown判斷鼠標(biāo)點(diǎn)擊的位置是否在觸發(fā)控件的位置,如果是,mousemove的時(shí)候clone一個(gè)控件,修改透明度,然后放入容器內(nèi)的時(shí)候remove這個(gè)控件,并且在容器內(nèi)生成一個(gè)放入的控件(放入的控件和觸發(fā)的控件可以不一樣)
拖拽:同樣的, mousedown的時(shí)候判斷是哪個(gè)控件,mousemove的時(shí)候需要放一個(gè)占位div放在原有的位置上,并將元素修改透明度然后設(shè)置為絕對(duì)定位方便拖動(dòng),在進(jìn)行拖動(dòng)的時(shí)候,占位div也會(huì)跟著鼠標(biāo)位置進(jìn)行改變(判斷當(dāng)前鼠標(biāo)位置是否是容器內(nèi)控件的左上角加上控件高度的一半),放下的時(shí)候進(jìn)行判斷占位div的位置進(jìn)行插入。具體看代碼吧,這個(gè)思路加上的時(shí)間距離代碼實(shí)現(xiàn)的時(shí)間有點(diǎn)久遠(yuǎn)了,所有可能不是很準(zhǔn)確,但是大概的思路就是這樣了。
ps:要用到拖拽表單功能的,基本上可能都會(huì)要更改以往設(shè)計(jì)數(shù)據(jù)庫方式,這里可以提供給你們一個(gè)搜索關(guān)鍵詞 表的縱向存儲(chǔ)
注釋基本上都已經(jīng)寫的很詳細(xì)了,直接上代碼吧。
有什么問題請(qǐng)大神們多多指教
<!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"> //要傳入的變量 //點(diǎn)擊觸發(fā)的對(duì)象 var click = document.getElementById("title"); var click2 = document.getElementById("title2"); //放入的容器 var box = document.getElementById("box"); //容器內(nèi)占位的DIV var place = document.createElement("div"); place.className = "place"; //往容器內(nèi)添加的對(duì)象 var create = document.createElement("input"); create.type = "text"; var create2 = document.createElement("input"); create2.type = "password"; //是否可以添加多個(gè) var isMany = true; createWin(click,create,isMany,place,box); createWin(click2,create2,isMany,place,box); </script> </html>
/** * author:lzh * 作用:可拖拽排序表單實(shí)現(xiàn) * 參數(shù):oclick 點(diǎn)擊觸發(fā)事件的對(duì)象 * ocreate 出發(fā)后在表單中傳入的對(duì)象 * bisMany 單個(gè)oclick對(duì)象是否可拖入多個(gè)ocreate對(duì)象 * oplace 拖入時(shí)占位div對(duì)象 * obox 拖入的容器,不填則默認(rèn)為body */ function createWin(oclick,ocreate,bisMany,oplace,obox=document.body) { //是否點(diǎn)擊了觸發(fā)對(duì)象 var isClick = false; //觸發(fā)對(duì)象是否為容器內(nèi)的元素 var isIncludeBox = false; oplace.style.width = obox.offsetWidth-5 + "px"; oplace.style.height = oclick.offsetHeight-5 + "px"; //移動(dòng)效果的臨時(shí)元素 var oclickClone; var oclickDown; //計(jì)算偏移量 var diffObj; var diffX; var diffY; var tmp; var omove_position; //點(diǎn)是否包含在容器內(nèi) 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; } //移動(dòng)效果函數(shù) 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; } //鼠標(biāo)按下事件 function down(e) { if(isInclude(e.clientX,e.clientY,oclick)) { isClick = true; //克隆點(diǎn)擊的觸發(fā)節(jié)點(diǎn) oclickClone=oclick.cloneNode(true); //計(jì)算鼠標(biāo)的偏移量(如果有margin的話會(huì)有偏移現(xiàn)象) getdiff(e); } else { getdiff(e); var child = obox.childNodes; for(var i=0; i < child.length; i++) { //判斷鼠標(biāo)點(diǎn)擊是否是容器內(nèi)的元素,并且不能是占位div(如果不加這個(gè)占位div判斷會(huì)有bug,具體原因不知道) if(isInclude(e.clientX,e.clientY,child[i])&& child[i] != oplace) { isClick = true; isIncludeBox = true; //克隆元素用來拖動(dòng)時(shí)的效果 oclickClone = child[i].cloneNode(true); //克隆元素用來放下 oclickDown = child[i].cloneNode(true); //按下之后刪除元素,并使用移動(dòng)效果來展示元素 obox.removeChild(child[i]); moveMagic(oclickClone,e); //插入占位div來弄 obox.insertBefore(oplace,child[i]); // flag = true; break; } } } } //鼠標(biāo)移動(dòng)事件 function move(e) { if(isClick) { moveMagic(oclickClone,e); //判斷鼠標(biāo)是否移動(dòng)到了容器內(nèi)部 if(isInclude(e.clientX,e.clientY,obox)) { //計(jì)算容器內(nèi)的子節(jié)點(diǎn) var child = obox.childNodes; //一旦進(jìn)入就可以在首位置插入占位DIV obox.insertBefore(oplace,child[0]); //根據(jù)鼠標(biāo)位置放置占位DIV for(var i = 0; i < child.length; i++) { //因?yàn)檎嘉籇IV是唯一的,所以只需要這樣判斷即可 if(e.clientY > child[i].offsetTop+child[i].offsetHeight/2) { //判斷是否拖動(dòng)到了結(jié)尾 if(i != child.length-1) obox.insertBefore(oplace,child[i+1]); else obox.appendChild(oplace); } } } } } //鼠標(biāo)抬起事件 function up(e) { isClick = false; //鼠標(biāo)抬起則可以刪除臨時(shí)的拖動(dòng)效果元素 document.body.removeChild(oclickClone); //如果將元素放置到了容器內(nèi) 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; } } //判斷是否可以放置多個(gè) if(!bisMany) { if(isIncludeBox) ocreate = oclickDown; if(insertPlace==child.length) obox.appendChild(ocreate); else obox.insertBefore(ocreate,child[insertPlace]); } else { //可以放置多個(gè)則需要每個(gè)都克隆一下 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實(shí)現(xiàn)可拖拽表單的簡(jiǎn)單實(shí)例就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
前端使用axios實(shí)現(xiàn)下載文件功能的詳細(xì)過程
項(xiàng)目中經(jīng)常會(huì)遇到需要導(dǎo)出列表內(nèi)容,或者下載文件之類的需求,下面這篇文章主要給大家介紹了關(guān)于前端使用axios實(shí)現(xiàn)下載文件功能的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08Vue3中使用typescript封裝axios的實(shí)例詳解
這篇文章主要介紹了使用typescript封裝axios的實(shí)例代碼,為了方便,在vue3的配置里面按需加載element-plus,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2021-10-10JavaScript運(yùn)行機(jī)制之事件循環(huán)(Event Loop)詳解
這篇文章主要介紹了JavaScript運(yùn)行機(jī)制之事件循環(huán)(Event Loop)詳解,本文從多個(gè)方面講解了Event Loop,需要的朋友可以參考下2014-10-10中級(jí)前端工程師必須要掌握的27個(gè)JavaScript 技巧(干貨總結(jié))
這篇文章主要介紹了中級(jí)前端工程師必須要掌握的27個(gè)JavaScript 技巧(干貨總結(jié)),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-09-09Bootstrap實(shí)現(xiàn)省市區(qū)三級(jí)聯(lián)動(dòng)(親測(cè)可用)
這篇文章主要為大家詳細(xì)介紹了Bootstrap實(shí)現(xiàn)省市區(qū)三級(jí)聯(lián)動(dòng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07js實(shí)現(xiàn)html滑動(dòng)圖片拼圖驗(yàn)證
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)html滑動(dòng)圖片拼圖驗(yàn)證,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06為什么JavaScript中0.1 + 0.2 != 0.3
這篇文章主要給大家介紹了關(guān)于為什么JavaScript中0.1 + 0.2 != 0.3的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12js實(shí)現(xiàn)點(diǎn)擊圖片改變頁面背景圖的方法
這篇文章主要介紹了js實(shí)現(xiàn)點(diǎn)擊圖片改變頁面背景圖的方法,實(shí)例分析了javascript操作css與圖片的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-02-02