可拖动元素拖动到另外一个元素位置的时候,互相交换位置。
来源:最初是网上看到的一个拼图小游戏,具体网址不记得了,这块是单独扒出来的。
代码:
body,ul,li{margin:0;padding:0;} ul{list-style: none;} body{font:13px/1.5 Tahoma;} #box{position:relative;width:435px;height:580px;margin:10px auto;padding: 10px 5px 10px 10px;border: 1px solid #ccc;} #box li{float:left;width:80px;height:188px;overflow:hidden;background: #ccc;border: 1px solid #999;} #box li.hig{width:78px;height:186px;overflow:hidden;border:2px dashed blue;}
<ul id="box"></ul>
1 var zIndex = 1; 2 window.onload = function() { 3 4 var oBox = document.getElementById("box"); 5 var aLi = oBox.getElementsByTagName("li"); 6 var aPos = []; 7 var aData = []; 8 for (i = 0; i < 15; i++)aData.push(i+1); 9 10 11 //插入结构 12 var oFragment = document.createDocumentFragment(); 13 for (i = 0; i < aData.length; i++) { 14 var oLi = document.createElement("li"); 15 oFragment.appendChild(oLi) 16 } 17 oBox.appendChild(oFragment); 18 19 //布局转换 20 for (i = 0; i < aLi.length; i++) { 21 aLi[i].index = i; 22 aLi[i].style.top = aLi[i].offsetTop + "px"; 23 aLi[i].style.left = aLi[i].offsetLeft + "px"; 24 aLi[i].style.margin = "0 5px 5px 0"; 25 aPos.push({ 26 "left": aLi[i].offsetLeft, 27 "top": aLi[i].offsetTop 28 }) 29 } 30 for (i = 0; i < aLi.length; i++) { 31 aLi[i].style.position = "absolute"; 32 drag(aLi[i]) 33 } 34 35 //拖拽函数 36 function drag(obj, handle) { 37 var handle = handle || obj; 38 handle.style.cursor = "move"; 39 handle.onmousedown = function(event) { 40 var event = event || window.event; 41 var disX = event.clientX - this.offsetLeft; 42 var disY = event.clientY - this.offsetTop; 43 var oNear = null; 44 obj.style.zIndex = zIndex++; 45 document.onmousemove = function(event) { 46 var event = event || window.event; 47 var iL = event.clientX - disX; 48 var iT = event.clientY - disY; 49 var maxL = obj.parentNode.clientWidth - obj.offsetWidth; 50 var maxT = obj.parentNode.clientHeight - obj.offsetHeight; 51 52 iL < 0 && (iL = 0); 53 iT < 0 && (iT = 0); 54 iL > maxL && (iL = maxL); 55 iT > maxT && (iT = maxT); 56 obj.style.left = iL + "px"; 57 obj.style.top = iT + "px"; 58 59 for (i = 0; i < aLi.length; i++) aLi[i].className = ""; 60 61 oNear = findNearest(obj); 62 63 oNear && (oNear.className = "hig"); 64 65 return false 66 }; 67 document.onmouseup = function() { 68 document.onmousemove = null; 69 document.onmouseup = null; 70 if (oNear) { 71 var tIndex = obj.index; 72 obj.index = oNear.index; 73 oNear.index = tIndex; 74 startMove(obj, aPos[obj.index]); 75 startMove(oNear, aPos[oNear.index], function() { 76 77 }); 78 oNear.className = ""; 79 } else { 80 startMove(obj, aPos[obj.index]) 81 } 82 handle.releaseCapture && handle.releaseCapture() 83 }; 84 this.setCapture && this.setCapture(); 85 return false 86 } 87 } 88 89 //找出相遇点中最近的元素 90 function findNearest(obj) { 91 var filterLi = []; 92 var aDistance = []; 93 94 for (i = 0; i < aLi.length; i++) aLi[i] != obj && (isButt(obj, aLi[i]) && (aDistance.push(getDistance(obj, aLi[i])), filterLi.push(aLi[i]))); 95 96 var minNum = Number.MAX_VALUE; 97 var minLi = null; 98 99 for (i = 0; i < aDistance.length; i++) aDistance[i] < minNum && (minNum = aDistance[i], minLi = filterLi[i]); 100 101 return minLi 102 } 103 104 105 106 }; 107 //求两点之间的距离 108 function getDistance(obj1, obj2) { 109 var a = (obj1.offsetLeft + obj1.offsetWidth / 2) - (obj2.offsetLeft + obj2.offsetWidth / 2); 110 var b = (obj1.offsetTop + obj1.offsetHeight / 2) - (obj2.offsetTop + obj2.offsetHeight / 2); 111 return Math.sqrt(a * a + b * b) 112 } 113 114 //碰撞检测 115 function isButt(obj1, obj2) { 116 var l1 = obj1.offsetLeft; 117 var t1 = obj1.offsetTop; 118 var r1 = obj1.offsetLeft + obj1.offsetWidth; 119 var b1 = obj1.offsetTop + obj1.offsetHeight; 120 121 var l2 = obj2.offsetLeft; 122 var t2 = obj2.offsetTop; 123 var r2 = obj2.offsetLeft + obj2.offsetWidth; 124 var b2 = obj2.offsetTop + obj2.offsetHeight; 125 126 return !(r1 < l2 || b1 < t2 || r2 < l1 || b2 < t1) 127 } 128 129 //获取最终样式 130 function getStyle(obj, attr) { 131 return parseFloat(obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj, null)[attr]) 132 } 133 134 //运动框架 135 function startMove(obj, pos, onEnd) { 136 clearInterval(obj.timer); 137 obj.timer = setInterval(function() { 138 doMove(obj, pos, onEnd) 139 }, 30) 140 } 141 142 function doMove(obj, pos, onEnd) { 143 var iCurL = getStyle(obj, "left"); 144 var iCurT = getStyle(obj, "top"); 145 var iSpeedL = (pos.left - iCurL) / 5; 146 var iSpeedT = (pos.top - iCurT) / 5; 147 iSpeedL = iSpeedL > 0 ? Math.ceil(iSpeedL) : Math.floor(iSpeedL); 148 iSpeedT = iSpeedT > 0 ? Math.ceil(iSpeedT) : Math.floor(iSpeedT); 149 if (pos.left == iCurL && pos.top == iCurT) { 150 clearInterval(obj.timer); 151 onEnd && onEnd() 152 } else { 153 obj.style.left = iCurL + iSpeedL + "px"; 154 obj.style.top = iCurT + iSpeedT + "px"; 155 } 156 }
预览图