原生JS實(shí)現(xiàn)拖拽照片墻
本文實(shí)例為大家分享了一個(gè)用原生JS實(shí)現(xiàn)的可拖拽照片墻,效果如下:
實(shí)現(xiàn)代碼如下:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>原生JS實(shí)現(xiàn)拖拽照片墻,實(shí)現(xiàn)照片互換位置</title> <style> * { margin: 0; padding: 0; } #ul1 { width: 660px; position: relative; margin: 10px auto; } #ul1 li { width: 200px; height: 150px; float: left; list-style: none; margin: 10px; z-index: 1; } #ul1 .active { border: 1px dashed red; } </style> <script src="js/move.js"></script> <script> window.onload = function () { var oUl = document.getElementById('ul1'); var aLi = oUl.getElementsByTagName('li'); var aPos = []; var iMinZindex = 2; var i = 0; //布局轉(zhuǎn)換 //獲取當(dāng)前布局圖片的位置 for (i = 0; i < aLi.length; i++) { aPos[i] = { left: aLi[i].offsetLeft, top: aLi[i].offsetTop }; } //布局轉(zhuǎn)換必須要兩個(gè)for循環(huán)才能完成 for (i = 0; i < aLi.length; i++) { //為每個(gè)圖片位置賦值 aLi[i].style.left = aPos[i].left + 'px'; aLi[i].style.top = aPos[i].top + 'px'; //轉(zhuǎn)換定位 aLi[i].style.position = 'absolute'; //offset的值經(jīng)已經(jīng)包括的margin值,所以要取消 aLi[i].style.margin = '0'; aLi[i].index = i; } //循環(huán)拖拽 for (i = 0; i < aLi.length; i++) { setDrag(aLi[i]); } function setDrag(obj) { //當(dāng)鼠標(biāo)按下時(shí) obj.onmousedown = function (ev) { //事件兼容 var oEvent = ev || event; //將當(dāng)前圖片的堆疊順序增加 obj.style.zIndex = iMinZindex++; //計(jì)算鼠標(biāo)相對于拖拽對象左上角的位置 var disX = oEvent.clientX - obj.offsetLeft; var disY = oEvent.clientY - obj.offsetTop; //當(dāng)鼠標(biāo)移動時(shí) document.onmousemove = function (ev) { //事件兼容 var oEvent = ev || event; //重新為圖片位置賦值 obj.style.left = oEvent.clientX - disX + 'px'; obj.style.top = oEvent.clientY - disY + 'px'; //清空所有l(wèi)i的樣式 for (i = 0; i < aLi.length; i++) { aLi[i].className = ''; } //獲取當(dāng)前拖拽對象的最近目標(biāo)對象 var oNear = findNearest(obj); //如果存在 if (oNear) { //將該對象的class賦于active oNear.className = 'active'; } }; //當(dāng)鼠標(biāo)松開時(shí) document.onmouseup = function () { document.onmousemove = null; document.onmouseup = null; //獲取當(dāng)前拖拽對象的最近目標(biāo)對象 var oNear = findNearest(obj); //如果有最近的碰撞對象 if (oNear) { oNear.className = ''; //將最近目標(biāo)對象的zIndex加加 //防止從背面移動 oNear.style.zIndex = iMinZindex++; //當(dāng)前拖拽對象移到目標(biāo)對象之上時(shí)位于目標(biāo)對象之上 obj.style.zIndex = iMinZindex++; //將最近目標(biāo)對象(oNear)移到當(dāng)前對象(obj)位置 startMove(oNear, aPos[obj.index]); //將當(dāng)前對象(obj)移到最近目標(biāo)對象(oNear)位置 startMove(obj, aPos[oNear.index]); //交換當(dāng)前拖拽對象與目標(biāo)對象的index值 var tmp = 0; tmp = obj.index; obj.index = oNear.index; oNear.index = tmp; //如果沒有最近的碰撞對象 } else { //回到原位 startMove(obj, aPos[obj.index]); } }; //清除定時(shí)器 //防止圖片在移位過程中再次拖動出現(xiàn)抖動 clearInterval(obj.timer); //防止瀏覽器bug,拖拽時(shí)鼠標(biāo)指針變形 return false; }; } //碰撞檢測 function cdTest(obj1, obj2) { //目標(biāo)1的左右上下輪廓位置 var l1 = obj1.offsetLeft; var r1 = obj1.offsetLeft + obj1.offsetWidth; var t1 = obj1.offsetTop; var b1 = obj1.offsetTop + obj1.offsetHeight; //目標(biāo)2的左右上下輪廓位置 var l2 = obj2.offsetLeft; var r2 = obj2.offsetLeft + obj2.offsetWidth; var t2 = obj2.offsetTop; var b2 = obj2.offsetTop + obj2.offsetHeight; //對兩個(gè)目標(biāo)的外輪廓線進(jìn)行對比,以檢測是否碰撞到了 if (r1 < l2 || l1 > r2 || b1 < t2 || t1 > b2) { return false; } else { return true; } } //計(jì)算拖拽對象和其它對象的連線距離 function getDis(obj1, obj2) { var a = obj1.offsetLeft - obj2.offsetLeft; var b = obj1.offsetTop - obj2.offsetTop; return Math.sqrt(a * a + b * b); } //找到碰上的,并且最近的 function findNearest(obj) { //為找出最小值做的參照數(shù)值 var iMin = 999999999; var iMinIndex = -1; for (i = 0; i < aLi.length; i++) { //避免自身與自身相碰撞,跳過檢測 if (obj == aLi[i]) { continue }; //如果找到碰撞對象 if (cdTest(obj, aLi[i])) { //計(jì)算拖拽對象與每個(gè)li的距離 var dis = getDis(obj, aLi[i]); //如果當(dāng)前參照距離大于某一個(gè)li與當(dāng)前拖拽對象的距離 if (iMin > dis) { //重新賦值參照距離(多次比對,得出最小值) iMin = dis; //得出最近目標(biāo)的下標(biāo) iMinIndex = i; } } } //iMinIndex為-1,代表始終沒有碰到 if (iMinIndex == -1) { return null; //否則 } else { //返回碰撞最近的那個(gè)li return aLi[iMinIndex]; } } }; </script> </head> <body> <ul id="ul1"> <li><img src="images/0.jpg" /></li> <li><img src="images/1.jpg" /></li> <li><img src="images/2.jpg" /></li> <li><img src="images/3.jpg" /></li> <li><img src="images/4.jpg" /></li> <li><img src="images/0.jpg" /></li> <li><img src="images/1.jpg" /></li> <li><img src="images/2.jpg" /></li> <li><img src="images/3.jpg" /></li> <li><img src="images/4.jpg" /></li> </ul> </body> </html>
以下是上面代碼中引入的move.js文件,主要用于實(shí)現(xiàn)運(yùn)動效果,代碼如下:
function getStyle(obj, attr) { if (obj.currentStyle) { return obj.currentStyle[attr]; } else { return getComputedStyle(obj, false)[attr]; } } function startMove(obj, json, fn) { clearInterval(obj.timer); obj.timer = setInterval(function () { var bStop = true; for (var attr in json) { var iCur = 0; if (attr == 'opacity') { iCur = parseInt(parseFloat(getStyle(obj, attr)) * 100); } else { iCur = parseInt(getStyle(obj, attr)); } var iSpeed = (json[attr] - iCur) / 8; iSpeed = iSpeed > 0 ? Math.ceil(iSpeed) : Math.floor(iSpeed); if (iCur != json[attr]) { bStop = false; } if (attr == 'opacity') { obj.style.filter = 'alpha(opacity:' + (iCur + iSpeed) + ')'; obj.style.opacity = (iCur + iSpeed) / 100; } else { obj.style[attr] = iCur + iSpeed + 'px'; } } if (bStop) { clearInterval(obj.timer); if (fn) { fn(); } } }, 30) }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
js新聞滾動 js如何實(shí)現(xiàn)新聞滾動效果
JS實(shí)現(xiàn)新聞滾動效果:滾動頻率由setTimeout(F,#%18?10:3000)這個(gè)3000來控制,感興趣的朋友可以了解下哦2013-01-01JS時(shí)間戳與日期格式互相轉(zhuǎn)換的簡單方法示例
這篇文章主要給大家介紹了關(guān)于JS時(shí)間戳與日期格式互相轉(zhuǎn)換的簡單方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11使用javascript做時(shí)間倒數(shù)讀秒功能的實(shí)例
今天小編就為大家分享一篇關(guān)于使用javascript做時(shí)間倒數(shù)讀秒功能的實(shí)例,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-01-01javascript設(shè)計(jì)模式 – 原型模式原理與應(yīng)用實(shí)例分析
這篇文章主要介紹了javascript設(shè)計(jì)模式 – 原型模式,結(jié)合實(shí)例形式分析了javascript原型模式相關(guān)概念、原理、應(yīng)用場景及操作注意事項(xiàng),需要的朋友可以參考下2020-04-04