前言
現在做頁面的經常會有用到拖拽的東西 ,我一直用的都是jquery的一些插件,但知其然,不知其所以然不是我想要的。起碼對於經常會用到的東西還是盡可能多去了解點,所以就百度百度,書翻幾下。想着自己也試着寫個可以拖拽並自動排列的例子,起碼了解一下。
輔助js(主要是簡化document.getElement(id) 這些的寫法)
如下代碼:(可略過不看 代碼最后會提供下載,並且不關拖拽具體實現)
View Code
1 (function (window) { 2 var regId = /^#[\w\-]+$/, 3 regCls = /^.[\w\-]+$/, 4 //從園子里某位前輩那里看來的(有點時間了 忘記在哪), Array.prototype.slice.call是把一個偽數組變為數組,具體百度 5 p_silice = Array.prototype.slice, 6 p_push = Array.prototype.push, 7 markArr = function (obj) { 8 return p_silice.call(obj, 0); 9 }; 10 function MWood(selector) { 11 return new MWood.prototype.init(selector); 12 }; 13 14 function MWood(selector, context) { 15 return new MWood.prototype.init(selector, context); 16 } 17 18 MWood.prototype = { 19 init: function (selector) { 20 if (regId.test(selector)) { 21 this.length = 1; 22 this[0] = document.getElementById(selector); 23 return this; 24 } 25 else if (regCls.test(selector)) { 26 if (document.querySelectorAll) { 27 p_push.apply(this, markArr(document.querySelectorAll(selector))); 28 } else { 29 var len = documenet.getElementsByTagName('*').length, 30 clsArr = [], 31 el, i = 0, 32 selector = selector.replace(/\-/g, "\\-"); 33 var oRegExp = new RegExp("(^|\\s)" + selector + "(\\s|$)"); 34 35 for (; i < len; i++) { 36 el = els[i]; 37 if (oRegExp.test(el[type])) { 38 clsArr.push(el); 39 } 40 } 41 42 pro_push.apply(this, markArr(clsArr)); 43 return this; 44 } 45 } 46 }, 47 length: 0 48 } 49 50 MWood.prototype.init.prototype = MWood.prototype; 51 52 MWood.extend = function (obj) { 53 for (var o in obj) { 54 this[o] = obj[o]; 55 } 56 } 57 58 MWood.extend({ 59 addHandle: function (elm, type, fn) { 60 if (elm.addEventListener) { 61 elm.addEventListener(type, fn, false); 62 } 63 else if (el.attachEvent) { 64 elm.attachEvent("on" + type, fn); 65 } else { 66 elm["on" + type] = fn; 67 } 68 }, 69 removeHandle: function (elm, type, fn) { 70 if (elm.removeEventListener) { 71 elm.removeEventListener(type, fn, false); 72 } 73 else if (el.detachEvent) { 74 elm.detachEvent("on" + type, fn); 75 } else { 76 elm["on" + type] = null; 77 } 78 }, 79 getEvent: function (evnet) { 80 return evnet ? evnet : window.evnet; 81 }, 82 getTarget: function (event) { 83 return event.target || event.srcElement; 84 } 85 }); 86 87 window.MWood = MWood; 88 89 })(this);
拖拽js
window.onload = function () { var dragDrop = function () { var dragInfo = {}; //存放有關拖拽對象的一些信息 function handleEvent(event) { e = MWood.getEvent(event); //獲得事件 var target = MWood.getTarget(event); //獲得事件對象 switch (event.type) { //判斷事件類型 case "mousedown": if (target.className.indexOf("droggle") > -1) { dragInfo.dObj = target; //存放事件對象 var tlwh = getObjtlwh(target); //獲得對象的 offsetTop,offsetLeft,offsetWidth,offsetHeight //計算出鼠標的坐標與對象offsetTop,offsetLeft的差值以便於鼠標移動時實時定位拖拽對象的位置 target.x = e.clientX - tlwh[1]; target.y = e.clientY - tlwh[0]; //修改對象的position以便可以設置left和top進行拖拽 從這里開始此對象已經脫離文檔流 //何為文檔流 當怎么樣設置position或別的設置會脫離文檔流請百度 target.style.position = "absolute"; //設置拖拽對象的left top width height target.style.left = tlwh[1] + "px"; target.style.top = tlwh[0] + "px"; target.style.width = tlwh[2] + "px"; target.style.height = tlwh[3] + "px"; //建立一個新對象填補被拖拽對象的位置,這樣頁面就還會按現在的排版,不會有任何更改。 //如果沒創建,被拖拽對象的位置就會被文檔流上的其他對象占用,文章最后提供代碼,可以注釋掉下面4句試下兩種情況 dragInfo.vObj = document.createElement("div"); dragInfo.vObj.style.width = target.style.width; dragInfo.vObj.style.height = target.style.height; target.parentNode.insertBefore(dragInfo.vObj, target); } break; case "mousemove": if (dragInfo.dObj) { //當鼠標移動的時候判斷時候已經有對象存在(對象會在mousedown的時候存放進這個變量里) //設置拖拽對象的left和top改變位置,因為position已經在mousedown的時候改變為absolute了(鼠標坐標-保存的差值) dragInfo.dObj.style.left = (e.clientX - dragInfo.dObj.x) + "px"; dragInfo.dObj.style.top = (e.clientY - dragInfo.dObj.y) + "px"; //獲取class為droggle的一組HTMl對象.Array.prototype.slice.call是給一個偽數組轉為真正的數組用的,MWood(".droggle")就是取得class為droggle的一組對象 var arr = Array.prototype.slice.call(MWood(".droggle"), 0); //循環對象 for (var i = 0; i < arr.length; i++) { if (arr[i] === dragInfo.dObj) //過濾拖拽對象 continue; var tlwh = getObjtlwh(arr[i]); //獲得對象的 offsetTop,offsetLeft,offsetWidth,offsetHeight //下面就主要是判斷鼠標的位置是否為引起頁面上各HTML元素在頁面上位置的替換 //判斷鼠標x > 對比對象offsetLeft && x < (對比對象的offsetWidth + 對象對象offsetLef)。 鼠標的坐標y同理鼠標坐標x的判斷 //判斷位置變換也可以按自己的標准來,我百度的時候看到例子里是這樣判斷我就直接像他那樣寫了 if (e.x > tlwh[1] && e.x < (tlwh[1] + tlwh[2]) && e.y > tlwh[0] && e.y < (tlwh[0] + tlwh[3])) { if (e.y < ((tlwh[0] + tlwh[3]) / 2)) { arr[i].parentNode.insertBefore(dragInfo.vObj, arr[i]); break; } else { if (!arr[i].nextSibling) { arr[i].parentNode.appendChild(dragInfo.vObj); break; } else { arr[i].parentNode.insertBefore(dragInfo.vObj, arr[i].nextSibling); break; } } } } } break; case "mouseup": if (dragInfo.dObj) { //把拖拽對象重新弄進文檔流(static就是默認的值),替換臨時占位的對象,並初始化dragInfo; dragInfo.dObj.style.position = "static"; dragInfo.vObj.parentNode.insertBefore(dragInfo.dObj, dragInfo.vObj); dragInfo.dObj.parentNode.removeChild(dragInfo.vObj); dragInfo = {}; } break; } }; //綁定事件 MWood.addHandle(document, "mousedown", handleEvent); MWood.addHandle(document, "mousemove", handleEvent); MWood.addHandle(document, "mouseup", handleEvent); } (); }; function getObjtlwh(o) { var arr = []; arr[0] = o.offsetTop; arr[1] = o.offsetLeft; arr[2] = o.offsetWidth; arr[3] = o.offsetHeight; return arr }
下載點擊
有什么問題或指教請留言。
