1. 程式人生 > 實用技巧 >九宮格拖拽

九宮格拖拽

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 
  4 <head>
  5     <meta charset="UTF-8">
  6     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7     <title>拖拽</title>
  8     <style>
  9         html,
 10         body {
 11             height: 100%;
12 width: 100%; 13 } 14 15 #main { 16 height: 470px; 17 width: 470px; 18 border: 1px solid #dddddd; 19 position: relative; 20 } 21 22 .item { 23 height: 150px; 24 width: 150px;
25 border: 1px solid #cccccc; 26 /* margin:10px 0 10px 10px; */ 27 position: absolute; 28 display: flex; 29 justify-content: center; 30 align-items: center; 31 font-size: 30px; 32 font-weight: 900; 33 }
34 35 .item1 { 36 background-color: aqua; 37 left: 0; 38 top: 0; 39 } 40 41 .item2 { 42 background-color: red; 43 left: 160px; 44 top: 0; 45 } 46 47 .item3 { 48 background-color: blanchedalmond; 49 left: 320px; 50 top: 0 51 } 52 53 .item4 { 54 background-color: yellowgreen; 55 left: 0; 56 top: 160px; 57 } 58 59 .item5 { 60 background-color: gold; 61 left: 160px; 62 top: 160px; 63 } 64 65 .item6 { 66 background-color: blueviolet; 67 left: 320px; 68 top: 160px; 69 } 70 71 .item7 { 72 background-color: thistle; 73 left: 0; 74 top: 320px; 75 } 76 77 .item8 { 78 background-color: salmon; 79 left: 160px; 80 top: 320px; 81 } 82 83 .item9 { 84 background-color: sienna; 85 left: 320px; 86 top: 320px; 87 } 88 </style> 89 </head> 90 91 <body> 92 <div id="main"> 93 <div class="item item1"> 94 1 95 </div> 96 <div class="item item2"> 97 2 98 </div> 99 <div class="item item3"> 100 3 101 </div> 102 <div class="item item4"> 103 4 104 </div> 105 <div class="item item5"> 106 5 107 </div> 108 <div class="item item6"> 109 6 110 </div> 111 <div class="item item7"> 112 7 113 </div> 114 <div class="item item8"> 115 8 116 </div> 117 <div class="item item9"> 118 9 119 </div> 120 </div> 121 </body> 122 <script type="text/javascript"> 123 window.onload = function () { 124 let domMian = document.getElementById('main') 125 let mainLeft = domMian.offsetWidth 126 let mianTop = domMian.offsetHeight 127 let divItem = document.getElementsByClassName('item') 128 let newLeft, newTop, oldLeft, oldTop 129 let index = 0 130 var arr = [] 131 for (let i = 0; i < divItem.length; i++) { 132 divItem[i].onmousedown = function (e) { 133 //每次都要去重新計算arr 134 arr=[] 135 for (let j = 0; j < divItem.length; j++) { 136 //左 上 右 下 137 arr.push([divItem[j].offsetLeft, divItem[j].offsetTop, divItem[j].offsetWidth + divItem[j].offsetLeft, divItem[j].offsetHeight + divItem[j].offsetTop]) 138 } 139 index = i 140 var e = e || window.event; //相容ie瀏覽器 141 oldLeft = divItem[i].offsetLeft 142 oldTop = divItem[i].offsetTop 143 var diffX = e.clientX - divItem[i].offsetLeft; //滑鼠點選物體那一刻相對於物體左側邊框的距離=點選時的位置相對於瀏覽器最左邊的距離-物體左邊框相對於瀏覽器最左邊的距離 144 var diffY = e.clientY - divItem[i].offsetTop; 145 divItem[i].style.zIndex = 99 146 /*低版本ie bug:物體被拖出瀏覽器可是視窗外部時,還會出現滾動條, 147 解決方法是採用ie瀏覽器獨有的2個方法setCapture()\releaseCapture(),這兩個方法, 148 可以讓滑鼠滑動到瀏覽器外部也可以捕獲到事件,而我們的bug就是當滑鼠移出瀏覽器的時候, 149 限制超過的功能就失效了。用這個方法,即可解決這個問題。注:這兩個方法用於onmousedown和onmouseup中*/ 150 if (typeof divItem[i].setCapture != 'undefined') { 151 divItem[i].setCapture(); 152 } 153 document.onmousemove = function (e) { 154 var e = e || window.event; //相容ie瀏覽器 155 var left = e.clientX - diffX; 156 var top = e.clientY - diffY; 157 //控制拖拽物體的範圍只能在main元素視窗內,不允許出現滾動條 158 if (left < 0) { 159 left = 0; 160 } else if (left > mainLeft - divItem[i].offsetWidth) { 161 left = mainLeft - divItem[i].offsetWidth; 162 } 163 if (top < 0) { 164 top = 0; 165 } else if (top > mianTop - divItem[i].offsetHeight) { 166 top = mianTop - divItem[i].offsetHeight 167 } 168 169 //移動時重新得到物體的距離,解決拖動時出現晃動的現象 170 divItem[i].style.left = left + 'px'; 171 divItem[i].style.top = top + 'px'; 172 newLeft = left 173 newTop = top 174 }; 175 document.onmouseup = function (e) { //當滑鼠彈起來的時候不再移動 176 this.onmousemove = null; 177 this.onmouseup = null; //預防滑鼠彈起來後還會迴圈(即預防滑鼠放上去的時候還會移動) 178 let newArr = [] 179 var newIndex = 0 180 // @碰撞原理 181 // 主動元素 A 被動元素 B 182 // A.top < B.bottom 3 && 183 // A.left < B.right 2&& 184 // A.right > B.left 0 && 185 // A.bottom > B.top 1 186 //左 上 右 下 記錄碰撞元素的個數 187 for (let k = 0; k < arr.length; k++) { 188 if (divItem[i].offsetTop < arr[k][3] && divItem[i].offsetLeft < arr[k][2] && newLeft + divItem[i].offsetWidth > arr[k][0] && newTop + divItem[i].offsetHeight > arr[k][1]) { 189 let newVal = { 190 'index': k, 191 'value': Math.abs(arr[k][0] - newLeft + arr[k][1] - newTop) 192 } 193 newArr.push(newVal) 194 } 195 } 196 let minIndex = newArr[0].value 197 /** 198 * @>= 是以免出現相等的情況 199 */ 200 for (let k = 0; k < newArr.length; k++) { 201 if (minIndex >= newArr[k].value) { 202 newIndex = newArr[k].index 203 } 204 } 205 divItem[i].style.left = divItem[newIndex].offsetLeft + 'px' 206 divItem[i].style.top = divItem[newIndex].offsetTop + 'px' 207 divItem[newIndex].style.left = oldLeft + 'px' 208 divItem[newIndex].style.top = oldTop + 'px' 209 divItem[i].style.zIndex = 0 210 //修復低版本ie bug 211 if (typeof divItem[i].releaseCapture != 'undefined') { 212 divItem[i].releaseCapture(); 213 } 214 } 215 }; 216 } 217 } 218 </script> 219 220 </html>