1. 程式人生 > 程式設計 >原生JS實現拖拽照片牆

原生JS實現拖拽照片牆

本文例項為大家分享了一個用原生實現的可拖拽照片牆,效果如下:

原生JS實現拖拽照片牆

實現程式碼如下:

<!DOCTYPE html>
<html>
 
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>原生JS實現拖拽照片牆,實現照片互換位置</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;
 
            //佈局轉換
 
            //獲取當前佈局圖片的位置
            for (i = 0; i < aLi.length; i++) {
 
                aPos[i] = { left: aLi[i].offsetLeft,top: aLi[i].offsetTop };
            }
            //佈局轉換必須要兩個for迴圈才能完成
            for (i = 0; i < aLi.length; i++) {
                //為每個圖片位置賦值
                aLi[i].style.left = aPos[i].left + 'px';
                aLi[i].style.top = aPos[i].top + 'px';
 
                //轉換定位
                aLi[i].style.position = 'absolute';
                //offset的值經已經包括的margin值,所以要取gcEDYuIK
消 aLi[i].style.margin = '0'; aLi[i].index = i; } //迴圈拖拽 for (i = 0; i < aLi.length; i++) { setDrag(aLi[i]); } function setDrag(obj) { //當滑鼠按下時 obj.onmousedown = function (ev) { //事件相容 var oEvent = ev || event; //將當前圖片的堆疊順序增加 obj.style.zIndex = iMinZindex++; //計算滑鼠相對於拖拽物件左上角的位置 var disX = oEvent.clientX - obj.offsetLeft; var disY = oEvent.clientY - obj.offsetTop; //當滑鼠移動時 document.onmousemove = function (ev) { //事件相容 var oEvent = ev || event; //重新為圖片位置賦值 obj.style.left = oEvent.clientX - disX + 'px'; obj.style.top = oEvent.clientY - disY + 'px'; //清空所有li的樣式 for (i = 0; i < aLi.length; i++) { aLi[i].className = ''; } //獲取當前拖拽物件的最近目標物件 var oNear = findNearest(obj); //如果存在 if (oNear) { //將該物件的class賦於active oNear.className = 'active'; } }; //當滑鼠鬆開時 document.onmouseup = function () { document.onmousemove = null; document.onmouseup = null; //獲取當前拖拽物件的最近目標物件 var oNear = findNearest(obj); //如果有最近的碰撞物件 if (oNear) { oNear.className = ''; //將最近目標物件的zIndex加加 //防止從背面移動 oNear.style.zIndex = iMinZindex++; //當前拖拽物件移到目標物件之上時位於目標物件之上 obj.style.zIndex = iMinZindex++; //將最近目標物件(oNear)移到當前物件(obj)位置 startMove(oNear,aPos[obj.index]);
//將當前物件(obj)移到最近目標物件(oNear)位置 startMove(obj,aPos[oNear.index]); //交換當前拖拽物件與目標物件的index值 var tmp = 0; tmp = obj.index; obj.index = oNear.index; oNear.index = tmp; //如果沒有最近的碰撞物件 } else { //回到原位 startMove(obj,aPos[obj.index]); } }; //清除定時器 //防止圖片在移位過程中再次拖動出現抖動 clearInterval(obj.timer); //防止瀏覽器bug,拖拽時滑鼠指標變形 gcEDYuIK
return false; }; } //碰撞檢測 function cdTest(obj1,obj2) { //目標1的左右上下輪廓位置 var l1 = obj1.offsetLeft; var r1 = obj1.offsetLeft + obj1.offsetWidth; var t1 = obj1.offsetTop; var b1 = obj1.offsetTop +www.cppcns.com obj1.offsetHeight; //目標2的左右上下輪廓位置 var l2 = obj2.offsetLeft; var r2 = obj2.offsetLeft + obj2.offsetWidth; var t2 = obj2.offsetTop; var b2 = obj2.offsetTop + obj2.offsetHeight; //對兩個目標的外輪廓線進行對比,以檢測是否碰撞到了 if (r1 < l2 || l1 > r2 || b1 < t2 || t1 > b2) { return false; } else { return true; } } //計算拖拽物件和其它物件的連線距離 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) { //為找出最小值做的參照數值 var iMin = 999999999; var iMinIndex = -1; for (i = 0; i < aLi.length; i++) { //避免自身與自身相碰撞,跳過檢測 if (obj == aLi[i]) { continue }; //如果找到碰撞物件 if (cdTest(obj,aLi[i])) { //計算拖拽物件與每個li的距離 var dis = getDis(obj,aLi[i]); //如果當前參照距離大於某一個li與當前拖拽物件的距離 if (iMin > dis) { //重新賦值參照距離(多次比對,得出最小值) iMin = dis; //得出最近目標的下標 iMinIndex = i; } } } //iMinIndex為-1,代表始終沒有碰到 if (iMinIndex == -1) { return null; //否則 } else { //返回碰撞最近的那個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檔案,主要用於實現運動效果,程式碼如下:

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)
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。