可拖动元素拖动到另外一个元素位置的时候,互相交换位置

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6     <meta http-equiv="X-UA-Compatible" content="ie=edge">
  7     <title>Document</title>
 16     <style>
 17         /* Unable to preventDefault inside passive event listener due to target being treated as passive */
 18         * { touch-action: none; }
 19         body,ul,li{margin:0;padding:0;}
 20         ul{list-style: none;}
 21         body{font:13px/1.5 Tahoma;width:100%;height:100%}
 22         html{width:100%;height:100%}
 23         #box{position:relative;width:100%;height:100%;}
 24         #box li{float:left;width:100%;height:50px;overflow:hidden;background: #ccc;border:2px solid #999999;}
 25         #box li.hig{width:100%;height:50px;overflow:hidden;border:2px dashed blue;} 
 26     </style>
 27 </head>
 28 <body>
 29     <ul id="box"></ul>
 30     <script>
 31         let zIndex = 1
 32         window.onload = function() {
 33             let oBox = document.getElementById("box")
 34             let aLi = oBox.getElementsByTagName("li")
 35             let aPos = []
 36             let aData = []
 37             for (let i = 0; i < 6; i++){
 38                 aData.push(i+1)
 39             }
 40             //插入结构
 41             let oFragment = document.createDocumentFragment()
 42             for (let i = 0; i < aData.length; i++) {
 43                 let oLi = document.createElement("li")
 44                 oLi.innerHTML = i+1
 45                 oFragment.appendChild(oLi)
 46             }
 47             oBox.appendChild(oFragment)
 48             //布局转换
 49             for (let i = 0; i < aLi.length; i++) {
 50                 aLi[i].index = i
 51                 aLi[i].style.top = Math.ceil(aLi[i].offsetTop) + "px"
 52                 aLi[i].style.left = Math.ceil(aLi[i].offsetLeft) + "px"
 53                 aLi[i].style.margin = "0 5px 5px 0"
 54                 aPos.push({
 55                     "left": aLi[i].offsetLeft,
 56                     "top": aLi[i].offsetTop
 57                 })
 58             }
 59             for (let i = 0; i < aLi.length; i++) {
 60                 aLi[i].style.position = "absolute"  
 61                 drag(aLi[i])
 62             }
 63 
 64             //拖拽函数
 65             function drag(obj, handle) {
 66                 let newHandle = handle || obj
 67                 newHandle.style.cursor = "move"
 68                 newHandle.onmousedown = newHandle.ontouchstart = function(evt) {
 69                     let event = evt || window.event
 70                     let disX,disY
 71                     if(event.type=='touchstart'){
 72                         let touch = event.touches[0]
 73                         disX = Number(touch.pageX) - this.offsetLeft
 74                         disY = Number(touch.pageY) - this.offsetTop
 75                     }else{
 76                         disX = event.clientX - this.offsetLeft
 77                         disY = event.clientY - this.offsetTop
 78                     }
 79                     let oNear = null
 80                     obj.style.zIndex = zIndex++
 81                     document.onmousemove = document.ontouchmove = function(evt) {
 82                         let event = evt || window.event
 83                         let iL,iT
 84                         if(event.type=='touchmove'){
 85                             let touch = event.touches[0]
 86                             iL = Number(touch.pageX) - disX
 87                             iT = Number(touch.pageY) - disY
 88                         }else{
 89                             iL = event.clientX - disX
 90                             iT = event.clientY - disY
 91                         }
 92                         
 93                         let maxL = obj.parentNode.clientWidth - obj.offsetWidth
 94                         let maxT = obj.parentNode.clientHeight - obj.offsetHeight
 95 
 96                         iL < 0 && (iL = 0)
 97                         iT < 0 && (iT = 0)
 98                         iL > maxL && (iL = maxL)
 99                         iT > maxT && (iT = maxT)
100                         obj.style.left = Math.ceil(iL) + "px"
101                         obj.style.top = Math.ceil(iT) + "px"
102 
103                         for (i = 0; i < aLi.length; i++){
104                             aLi[i].className = ""
105                         } 
106 
107                         oNear = findNearest(obj)
108 
109                         oNear && (oNear.className = "hig")
110 
111                         return false
112                     }
113                     document.onmouseup = document.ontouchend = function() {
114                         document.onmousemove = document.ontouchmove = null
115                         document.onmouseup = document.ontouchend = null
116                         if (oNear) {
117                             let tIndex = obj.index
118                             obj.index = oNear.index
119                             oNear.index = tIndex
120                             startMove(obj, aPos[obj.index])
121                             startMove(oNear, aPos[oNear.index], function() {})
122                             oNear.className = ""
123                             let data = [Number(obj.index)+1,Number(oNear.index)+1]
124                             let minNumber = Math.min.apply(Math,data)
125                             let maxNumber = Math.max.apply(Math,data)
126                             changeArraryElement(aData,minNumber,maxNumber)
127                             console.log('data之后',aData)
128                         } else {
129                             startMove(obj, aPos[obj.index])
130                         }
131                         newHandle.releaseCapture && newHandle.releaseCapture()
132                         // console.log('aData',aData)
133                         // console.log('aPos',aPos)
134                     }
135                     this.setCapture && this.setCapture()
136                     return false
137                 }
138             }
139 
140             //找出相遇点中最近的元素
141             function findNearest(obj) {
142                 let filterLi = []
143                 let aDistance = []
144                 for (i = 0; i < aLi.length; i++) aLi[i] != obj && (isButt(obj, aLi[i]) && (aDistance.push(getDistance(obj, aLi[i])), filterLi.push(aLi[i])))
145                 let minNum = Number.MAX_VALUE
146                 let minLi = null
147                 for (i = 0; i < aDistance.length; i++) aDistance[i] < minNum && (minNum = aDistance[i], minLi = filterLi[i])
148                 return minLi
149             }
150         }
151 
152         //求两点之间的距离
153         function getDistance(obj1, obj2) {
154             let a = (obj1.offsetLeft + obj1.offsetWidth / 2) - (obj2.offsetLeft + obj2.offsetWidth / 2)
155             let b = (obj1.offsetTop + obj1.offsetHeight / 2) - (obj2.offsetTop + obj2.offsetHeight / 2)
156             return Math.sqrt(a * a + b * b)
157         }
158 
159         //碰撞检测
160         function isButt(obj1, obj2) {
161             let l1 = obj1.offsetLeft
162             let t1 = obj1.offsetTop
163             let r1 = obj1.offsetLeft + obj1.offsetWidth
164             let b1 = obj1.offsetTop + obj1.offsetHeight
165 
166             let l2 = obj2.offsetLeft
167             let t2 = obj2.offsetTop
168             let r2 = obj2.offsetLeft + obj2.offsetWidth
169             let b2 = obj2.offsetTop + obj2.offsetHeight
170 
171             return !(r1 < l2 || b1 < t2 || r2 < l1 || b2 < t1)
172         }
173 
174         //获取最终样式
175         function getStyle(obj, attr) {
176             return parseFloat(obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj, null)[attr])
177         }
178 
179         //运动框架
180         function startMove(obj, pos, onEnd) {
181             clearInterval(obj.timer)
182             obj.timer = setInterval(function() {
183                 doMove(obj, pos, onEnd)
184             }, 30)
185         }
186 
187         function doMove(obj, pos, onEnd) {
188             let iCurL = getStyle(obj, "left")
189             let iCurT = getStyle(obj, "top")
190             let iSpeedL = (pos.left - iCurL) / 5
191             let iSpeedT = (pos.top - iCurT) / 5
192             iSpeedL = iSpeedL > 0 ? Math.ceil(iSpeedL) : Math.floor(iSpeedL)
193             iSpeedT = iSpeedT > 0 ? Math.ceil(iSpeedT) : Math.floor(iSpeedT)
194             if (pos.left == iCurL && pos.top == iCurT) {
195                 clearInterval(obj.timer)
196                 onEnd && onEnd()
197             } else {
198                 obj.style.left = Math.ceil(iCurL + iSpeedL) + "px"
199                 obj.style.top = Math.ceil(iCurT + iSpeedT) + "px"
200             }
201         }
202 
203         //交换第几个元素的数组操作,注意:x>y
204         function changeArraryElement(arr1,x1,y1){
205             let arr = arr1
206             let x = x1, y = y1
207             arr.splice(x - 1, 1, ...arr.splice(y - 1, 1, arr[x - 1]))
208             return arr
209         }
210     </script>
211 </body>
212 </html>

猜你喜欢

转载自www.cnblogs.com/zhoudawei/p/9577314.html