九宫格拖拽

  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              100%;
 13         }
 14 
 15         #main {
 16             height: 470px;
 17              470px;
 18             border: 1px solid #dddddd;
 19             position: relative;
 20         }
 21 
 22         .item {
 23             height: 150px;
 24              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()
eleaseCapture(),这两个方法, 
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>
原文地址:https://www.cnblogs.com/xubaoer/p/14211847.html