1、佈局轉換;


2、設置每一張都比上一次層級高;


3、move時找最近的,把當前拖動元素傳進來 ,最終得到變量nL


4、每一個圖片都沒碰到的情況;


5、需要找最近元素


6、拖動元素傳進函數


7、碰到的3元素找最近的;


8、條件是碰到的並且不包括自身


9、如何找斜邊的最小值;勾股定理


10、使用勾股定理則又是一個方法


11、被拖動元素與找到的最近元素之間運動切換,並且索引切換


12、隨時排使用隨時函數生產;並且也要重置每個圖的索引

window.onload = function () {
//佈局轉換;
var _ul = document.getElementById('ul1')
var _li = _ul.getElementsByTagName('li')
var _inp = document.getElementById('input1')
var izindex = 2;
var arr = []
for (var i = 0; i < _li.length; i++) {
    arr.push([_li[i].offsetLeft, _li[i].offsetTop])
}
for (var i = 0; i < _li.length; i++) {
    _li[i].style.position = 'absolute'
    _li[i].style.left = arr[i][0] + 'px'
    _li[i].style.top = arr[i][1] + 'px'
    _li[i].style.margin = 0;
}
for (var i = 0; i < _li.length; i++) {
    _li[i].index = i;
    drag(_li[i])
}
_inp.onclick = function () { //每一個都要動;
    var randomArr = [0, 1, 2, 3, 4, 5, 6, 7, 8]
    randomArr.sort(function (a, b) {  //隨機排
        return Math.random() - 0.5;
    })
    for (var i = 0; i < _li.length; i++) {
        sMove2(_li[i], {left: arr[randomArr[i]][0], top: arr[randomArr[i]][1]})
        //修正拖動時索引;
        _li[i].index = randomArr[i];
    }
}
function drag(obj) {
    var disX = 0;
    var disY = 0;
    obj.onmousedown = function (ev) {
        obj.style.zIndex = izindex++; //每一張都比上一次層級高;
        var ev = ev || event;
        disX = ev.clientX - obj.offsetLeft;
        disY = ev.clientY - obj.offsetTop;
        document.onmousemove = function (ev) {
            var ev = ev || event;
            obj.style.left = ev.clientX - disX + 'px'
            obj.style.top = ev.clientY - disY + 'px'

            for (var i = 0; i < _li.length; i++) {
                _li[i].style.border = ''
            }
            var nL = nearLi(obj) //1、move時找最近的,把當前拖動元素傳進來 ,最終得到變量nL
            if (nL) {     //2、每一個圖片都沒碰到的情況;
                nL.style.border = '2px red solid'
            }

        }
        document.onmouseup = function () {
            document.onmousemove = document.onmouseup = null;
            //最近元素
            var nL = nearLi(obj) //拖動元素

            if (nL) {
                sMove2(nL, {left: arr[obj.index][0], top: arr[obj.index][1]})
                sMove2(obj, {left: arr[nL.index][0], top: arr[nL.index][1]})
                //索引對調
                nL.index = [nL.index, obj.index];
                obj.index = nL.index[0];
                nL.index = nL.index[1];

                nL.style.border = '';
            }
            else { //沒碰到時回到原始位置;
                sMove2(obj, {left: arr[obj.index][0], top: arr[obj.index][1]})
            }
        }
        return false;
    }
}

function pz(o1, o2) {
    var L1 = o1.offsetLeft;
    var R1 = o1.offsetLeft + o1.offsetWidth;
    var T1 = o1.offsetTop;
    var B1 = o1.offsetTop + o1.offsetHeight;

    var L2 = o2.offsetLeft;
    var R2 = o2.offsetLeft + o2.offsetWidth;
    var T2 = o2.offsetTop;
    var B2 = o2.offsetTop + o2.offsetHeight;

    if (R1 < L2 || L1 > R2 || B1 < T2 || T1 > B2) { //碰不到的四種情況
        return false;
    }
    else {
        return true;
    }
}

function nearLi(o) { //3、拖動元素傳進來;
    var v = 9999;
    var index = -1;
    for (var i = 0; i < _li.length; i++) {    //4、碰到的3元素找最近的;
        if (pz(o, _li[i]) && o != _li[i]) {    // 5碰到的並且不包括自身

            //6、_li[i]即為碰到的3個元素,這裏的jl調用3次,需要利用勾股定理;
            var c = jl(o, _li[i])     //8、3條斜邊得到了 ;
            if (c < v) {    //9、如何找斜邊的最小值;
                v = c;      //10、v = 最小值;
                index = i;  //11、位置,最近的li在整體的位置
            }
        }
    }
    if (index != -1) {
        return _li[index];   //12、return回找到的元素,給上面代碼加紅邊框;
    }
    else {
        return false;
    }
}

function jl(o1, o2) {  //7、兩元素求元素的斜邊 a邊與b邊;    o1為第一張圖,o2可能是其他3張圖 ,因為上面調用了3次;
    var a = o1.offsetLeft - o2.offsetLeft;
    var b = o1.offsetTop - o2.offsetTop;
    return Math.sqrt(a * a + b * b);
}


function sMove2(obj, json, fn) {
    clearInterval(obj._t)
    var iCur = 0;
    var _speed = 0;
    obj._t = setInterval(function () {
        var on = true;
        for (var attr in json) {
            var _target = json[attr]
            if (attr == 'opacity') {
                iCur = Math.round(css(obj, attr) * 100)
            }
            else {
                iCur = parseInt(css(obj, attr));
            }
            _speed = (_target - iCur) / 8;
            _speed = _speed > 0 ? Math.ceil(_speed) : Math.floor(_speed)
            if (iCur !== _target) {
                on = false
                if (attr == 'opacity') {
                    obj.style.opacity = (iCur + _speed) / 100
                    obj.style.filter = 'alpha(opacity=' + iCur + _speed + ')'
                }
                else {
                    obj.style[attr] = iCur + _speed + 'px'
                }
            }
        }
        if (on) {
            clearInterval(obj._t)
            fn && fn.call(obj)
        }
    }, 30)
}

function css(obj, attr) {
    return obj.currentStyle ? obj.currentStyle[attr] : getComputedStyle(obj) [attr]
}
}

See the Pen YympxY by elmok (@elmok) on CodePen.


<script async src="//assets.codepen.io/assets/embed/ei.js"></script>