<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script type="text/javascript" src="js/jquery.min.js"></script> <title>拖拽</title> <style> * { margin: 0; padding: 0; } ul { list-style: none; } #drag ul { width: 612px; } #drag ul li { width: 100px; height: 100px; float: left; border: 1px solid transparent; } #drag ul li img { width: 100px; height: 100px; } @media only screen and (max-width: 750px) { #drag ul { width: 100%; } #drag ul li { width: 100px; height: 100px; float: left; border: 1px solid transparent; } #drag ul li img { width: 100px; height: 100px; } } </style> </head> <body> <div id="drag"> <ul> <li> <img src="img/1.png" alt="1.jpg"> </li> <li> <img src="img/Request-1.png" alt="2.jpg"> </li> <li> <img src="img/logo.png" alt="4.jpg"> </li> <li> <img src="img/sold.jpg" alt="5.jpg"> </li> <li> <img src="img/1.png" alt="1.jpg"> </li> <li> <img src="img/Request-1.png" alt="2.jpg"> </li> <li> <img src="img/logo.png" alt="4.jpg"> </li> <li> <img src="img/sold.jpg" alt="5.jpg"> </li> <li> <img src="img/1.png" alt="1.jpg"> </li> <li> <img src="img/Request-1.png" alt="2.jpg"> </li> <li> <img src="img/logo.png" alt="4.jpg"> </li> <li> <img src="img/sold.jpg" alt="5.jpg"> </li> <li> <img src="img/1.png" alt="1.jpg"> </li> <li> <img src="img/Request-1.png" alt="2.jpg"> </li> <li> <img src="img/logo.png" alt="4.jpg"> </li> <li> <img src="img/sold.jpg" alt="5.jpg"> </li> <li> <img src="img/sold.jpg" alt="5.jpg"> </li> <li> <img src="img/logo.png" alt="4.jpg"> </li> </ul> </div> <script type="text/javascript"> if ( navigator.userAgent.match(/Mobi/i) || navigator.userAgent.match(/Android/i) || navigator.userAgent.match(/iPhone/i) ){ let liItems = $("li") // 获取到每个li let zIndex = 1 //定义li的层级 /** * 循环每个li获取他们的位置 * offsetLeft * offsetTop */ let distanceL = [] // 定义距离对象数组 for(let i = 0; i<liItems.length; i++) { distanceL.push( { left: parseInt(liItems.eq(i).offset().left), top: parseInt(liItems.eq(i).offset().top), } ) } // 把刚循环出来的位置值转换到图片的样式 for(let i = 0; i<liItems.length; i++) { liItems.eq(i).css('position',"absolute"); liItems.eq(i).css('left',distanceL[i].left + 'px'); liItems.eq(i).css('top',distanceL[i].top + 'px'); liItems.eq(i).css('margin',0); liItems.eq(i).data('index',i); } // 拖拽功能 for (let i = 0; i < liItems.length; i++) { drag(liItems.eq(i)) } /** * 拖拽函数 */ function drag(obj) { // 给该对象绑定鼠标按下事件 obj.on("touchstart",function(e) { // 获取当前鼠标点击的位置 let x = e.originalEvent.targetTouches[0].pageX; let y = e.originalEvent.targetTouches[0].pageY; // 获取当前图片的位置 let left = obj.offset().left; let top = obj.offset().top; // 设置li的层级不断往上加 obj.css('zIndex',zIndex++); // 移动过程中 obj.on("touchmove",function(e) { // 获取移动中的位置,减去点击时候的位置,再加上图片原来的位置 let moveLeft = e.originalEvent.changedTouches[0].pageX - x + left let moveTop = e.originalEvent.changedTouches[0].pageY - y + top obj.css('left',moveLeft + "px"); obj.css('top',moveTop + "px"); // 移动的时候先把边框去掉 for(let i = 0; i< liItems.length; i++) { liItems.eq(i).css('border',"1px solid transparent"); } // 检测碰撞 let hit = nearLi(obj) if(hit) { hit.css('border',"1px dashed red"); } }) // 当鼠标抬起的时候,需要把鼠标松开事件改为null obj.on("touchend",function(e) { obj.off('touchmove touchend'); // 抬起来的时候再次获取碰撞的数据 let oLi = nearLi(obj); if(oLi){ oLi.off('touchmove touchend'); // 交换位置 animate(obj, {left: distanceL[oLi.data('index')].left, top: distanceL[oLi.data('index')].top},10, 0.08); animate(oLi, {left: distanceL[obj.data('index')].left, top: distanceL[obj.data('index')].top},10, 0.08); // 清除交换的边框 oLi.css('border',"1px solid transparent"); // 交换索引 let temp = obj.data('index'); obj.data('index',oLi.data('index')) ; oLi.data('index',temp); }else{ animate(obj, {left: distanceL[obj.data('index')].left, top: distanceL[obj.data('index')].top},10, 0.08); } }) //返回false是为了屏蔽h5中图片标签<img>默认的拖拽事件 return false; }) } // 计算最小距离 function nearLi(obj) { let n = 10000000000; let hit = ''; for (let i = 0; i < liItems.length; i++) { if (!obj.is(liItems.eq(i)) && impact(obj, liItems.eq(i))) { // 计算碰撞的li距离 let c = distance(obj, liItems.eq(i)); if (c < n) { n = c; hit = liItems.eq(i); } } } return hit; } // 碰撞检查 function impact(obj1, obj2) { //对象1的各各边距 let left1 = obj1.offset().left; //左边距 let top1 = obj1.offset().top; //上边距 let right1 = left1 + obj1.outerWidth(); //对象右边距离屏幕左边的距离 let bottom1 = top1 + obj1.outerHeight(); //对象下边距离屏幕顶端的距离 //对象2的各各边距 let left2 = obj2.offset().left; let top2 = obj2.offset().top; let right2 = left2 + obj2.outerWidth(); let bottom2 = top2 + obj2.outerHeight(); if (right1 <= left2 || bottom1 <= top2 || left1 >= right2 || top1 >= bottom2) { return false; } else { return true; } } // 勾股定理计算斜边 function distance(obj1, obj2) { let a = obj1.offset().left - obj2.offset().left; let b = obj1.offset().top - obj2.offset().top; return Math.sqrt(a * a + b * b); } function animate(obj, json, interval, sp, fn) { clearInterval(obj.timer); function getStyle(obj, arr) { return obj.css(arr); } obj.timer = setInterval(function(){ let flag = true; for(let arr in json) { let icur = 0; if(arr == "opacity") { icur = Math.round(parseFloat(getStyle(obj, arr))*100); } else { icur = parseInt(getStyle(obj, arr)); } let speed = (json[arr] - icur) * sp; speed = speed > 0 ? Math.ceil(speed): Math.floor(speed); if(icur != json[arr]){ flag = false; } $('#stext').val(icur +'!='+ json[arr]+'-'+arr+':'+flag+':'+obj.data('index')); if(arr == "opacity"){ obj.css('filter',"alpha(opacity : '+(icur + speed)+' )"); obj.css('opacity',(icur + speed)/100); }else { obj.css(arr,icur + speed + "px"); } } if(flag){console.log('clear'); clearInterval(obj.timer); if(fn){ fn(); } } },interval); } }else{ let liItems = document.getElementsByTagName("li") // 获取到每个li let zIndex = 1 //定义li的层级 /** * 循环每个li获取他们的位置 * offsetLeft * offsetTop */ let distanceL = [] // 定义距离对象数组 for(let i = 0; i<liItems.length; i++) { distanceL.push( { left: liItems[i].offsetLeft, top: liItems[i].offsetTop } ) } // 把刚循环出来的位置值转换到图片的样式 for(let i = 0; i<liItems.length; i++) { liItems[i].index = i; liItems[i].style.position = "absolute"; liItems[i].style.left = distanceL[i].left + 'px'; liItems[i].style.top = distanceL[i].top + 'px'; liItems[i].style.margin = 0; } // 拖拽功能 for (let i = 0; i < liItems.length; i++) { drag(liItems[i]) } /** * 拖拽函数 */ function drag(obj) { // 给该对象绑定鼠标按下事件 obj.onmousedown = function(ev) { ev = ev || window.event // 获取当前鼠标点击的位置 let x = ev.clientX let y = ev.clientY // 获取当前图片的位置 let left = this.offsetLeft let top = this.offsetTop // 设置li的层级不断往上加 this.style.zIndex = zIndex++ // 移动过程中 document.onmousemove = function(ev) { ev = ev || window.event // 获取移动中的位置,减去点击时候的位置,再加上图片原来的位置 let moveLeft = ev.clientX - x + left let moveTop = ev.clientY - y + top obj.style.left = moveLeft + "px" obj.style.top = moveTop + "px" // 移动的时候先把边框去掉 for(let i = 0; i< liItems.length; i++) { liItems[i].style.border = "1px solid transparent" } // 检测碰撞 let hit = nearLi(obj) if(hit) { hit.style.border = "1px dashed red" } } // 当鼠标抬起的时候,需要把鼠标松开事件改为null document.onmouseup = function() { document.onmousemove = null; document.onmouseup = null; // 抬起来的时候再次获取碰撞的数据 let oLi = nearLi(obj); if(oLi){ // 交换位置 animate(obj, {left: distanceL[oLi.index].left, top: distanceL[oLi.index].top},10, 0.08); animate(oLi, {left: distanceL[obj.index].left, top: distanceL[obj.index].top},10, 0.08); // 清除交换的边框 oLi.style.border = "1px solid transparent"; // 交换索引 console.log(obj.index); let temp = obj.index; obj.index = oLi.index; oLi.index = temp; console.log(obj.index); }else{ animate(obj, {left: distanceL[obj.index].left, top: distanceL[obj.index].top},10, 0.08); // obj.style.left = arr[obj.index].left+"px"; // obj.style.top = arr[obj.index].top+"px"; } } //返回false是为了屏蔽h5中图片标签<img>默认的拖拽事件 return false; } } // 计算最小距离 function nearLi(obj) { let n = 10000000000; let hit = ''; for (let i = 0; i < liItems.length; i++) { if (obj != liItems[i] && impact(obj, liItems[i])) { // 计算碰撞的li距离 let c = distance(obj, liItems[i]); if (c < n) { n = c; hit = liItems[i]; } } } return hit; } // 碰撞检查 function impact(obj1, obj2) { //对象1的各各边距 let left1 = obj1.offsetLeft; //左边距 let top1 = obj1.offsetTop; //上边距 let right1 = left1 + obj1.offsetWidth; //对象右边距离屏幕左边的距离 let bottom1 = top1 + obj1.offsetHeight; //对象下边距离屏幕顶端的距离 //对象2的各各边距 let left2 = obj2.offsetLeft; let top2 = obj2.offsetTop; let right2 = left2 + obj2.offsetWidth; let bottom2 = top2 + obj2.offsetHeight; if (right1 <= left2 || bottom1 <= top2 || left1 >= right2 || top1 >= bottom2) { // console.log("不成功") // 不成功 return false; } else { // console.log("成功") //成功 return true; } } // 勾股定理计算斜边 function distance(obj1, obj2) { let a = obj1.offsetLeft - obj2.offsetLeft; let b = obj1.offsetTop - obj2.offsetTop; return Math.sqrt(a * a + b * b); } function animate(obj, json, interval, sp, fn) { clearInterval(obj.timer); function getStyle(obj, arr) { if(obj.currentStyle){ return obj.currentStyle[arr]; //针对ie } else { return document.defaultView.getComputedStyle(obj, null)[arr]; } } obj.timer = setInterval(function(){ let flag = true; for(let arr in json) { let icur = 0; //k++; if(arr == "opacity") { icur = Math.round(parseFloat(getStyle(obj, arr))*100); } else { icur = parseInt(getStyle(obj, arr)); } let speed = (json[arr] - icur) * sp; speed = speed > 0 ? Math.ceil(speed): Math.floor(speed); if(icur != json[arr]){ flag = false; } if(arr == "opacity"){ obj.style.filter = "alpha(opacity : '+(icur + speed)+' )"; obj.style.opacity = (icur + speed)/100; }else { obj.style[arr] = icur + speed + "px"; } } if(flag){ clearInterval(obj.timer); if(fn){ fn(); } } },interval); } } </script> </body> </html>
标签:obj1,icur,arr,obj,拖动,let,移动,speed From: https://www.cnblogs.com/xmyfsj/p/17582950.html