零JS筆記 | 照片牆

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>

零JS筆記 | 圖片放大镜

问题:

<div id="div1">
    <div id="div2"></div>
</div>
<script>
    var _div1 = document.getElementById('div1')
    var _div2 = document.getElementById('div2')
    _div1.onmouseover = function () {
        document.title += 1
    }
    _div1.onmouseout = function () {
        document.title += 2
    }
</script>
<style>
    #div1 { width: 200px; height: 200px; background: red; }
    #div2 { width: 100px; height: 100px; background: yellow; }
</style>

從紅---> 黃 2121212121
1、觸發本身元素的out事件,所以+2,當到黃上,冒泡,又觸發本身的over事件+1
2、所以会发生闪动;

解决:
1、js: onmouseenter onmouseleave (子級不會影響父級 )
2、全兼容作法;
3、css: 加層隔開父子級;

window.onload = function () {
    var oDiv1 = document.getElementById('div1');
    var oDiv2 = document.getElementById('div2');

    oDiv1.onmouseover = function (ev) {
        var ev = ev || window.event;

        var a = this, b = ev.relatedTarget; //相對目標,之前的目標,移入目標之前的元素
        if (!elContains(a, b) && a != b) {
            document.title += '1';
        }
    };
    oDiv1.onmouseout = function (ev) {
        var ev = ev || window.event;

        var a = this, b = ev.relatedTarget;
        if (!elContains(a, b) && a != b) {
            document.title += '2';
        }
    };
};

function elContains(a, b) {  //判断两个元素是否是嵌套关系 a是否包含b
    return a.contains ? a != b && a.contains(b) : !!(a.compareDocumentPosition(b) & 16);
}

简单放大镜:

window.onload = function () {
    var _div = document.getElementById('div1')
    var _span = document.getElementsByTagName('span')[0]
    var _div2 = document.getElementById('div2')
    var _img2 = _div2.getElementsByTagName('img')[0]
    _div.onmouseover = function () {
        _span.style.display = 'block'
    }
    _div.onmouseout = function () {
        _span.style.display = 'none'
    }
    _div.onmousemove = function (e) {
        var e = e || event;
        var L = e.clientX - _div.offsetLeft - _span.offsetWidth / 2
        var T = e.clientY - _div.offsetTop - _span.offsetHeight / 2
        if (L < 0) {
            L = 0
        }
        else if (L > _div.offsetWidth - _span.offsetWidth) {
            L = _div.offsetWidth - _span.offsetWidth
        }
        if (T < 0) { //注意這裏不能寫else if
            T = 0
        }
        else if (T > _div.offsetHeight - _span.offsetHeight) {
            T = _div.offsetHeight - _span.offsetHeight
        }
        _span.style.left = L + 'px'
        _span.style.top = T + 'px'
        var scaleX = L / (_div.offsetWidth - _span.offsetWidth) //比例; 0-1
        var scaleY = T / (_div.offsetHeight - _span.offsetHeight) //比例:0-1
//大圖能走的距離為本身距離 - 大圖外層可視區的距離 ;
//此距離  * 比例

        _img2.style.left = -scaleX * (_img2.offsetWidth - _div2.offsetWidth) + 'px'
        _img2.style.top = -scaleY * (_img2.offsetHeight - _div2.offsetHeight) + 'px'


    }
}

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


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