天天看點

js原生--放大鏡(基礎版)正文部分自用庫引用部分 :

目錄

正文部分

自用庫引用部分 :

正文部分

<!DOCTYPE html>
<html >

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app"></div>
    <script src="/lianxi/JavaScript練習/自用庫01.js"></script>
    <script>
        //将圖檔與元素直接寫在頁面中,通過css寫樣式
        //封裝一個工具庫插件,可以在不同頁面中使用
        var app = document.getElementById('app');
        //使用插件//注:原生圖檔大小為400
        imageZoom(app, './圖檔/10.jpg', 400, 400);

        //将視圖繪制出來
        function imageZoom(dom, url, width, height) {
            //建立圖檔的兩種方式 : new Image () ; document.createElement('img')
            var mask = document.createElement('div');
            //放大的元素
            var big = document.createElement('div');
            //将元素放入app中
            app.appendChild(mask);
            app.appendChild(big);
            //設定樣式
            css(app, {
                width: width + 'px',
                height: height + 'px',
                position: 'relative',
                backgroundImage: 'url(' + url + ')',
                backgroundSize: 'cover',
                // border: '1px solid red',
                // top: '20px',
                // left: '20px'
            })
            //遮罩層
            css(mask, {
                width: width / 2 + 'px',
                height: height / 2 + 'px',
                position: 'absolute',
                top: 0,
                left: 0,
                backgroundColor: 'yellow',
                opacity: 0.5,
                cursor: 'move',
                display: 'none'
            })
            //設定右側放大器
            css(big, {
                width: width + 'px',
                height: height + 'px',
                position: 'absolute',
                top: 0,
                left: '100%',
                backgroundImage: 'url(' + url + ')',
                // border: '1px solid red',
                // display: 'none'
            })

            //函數體中局部的變量
            var x, y, top, left, maskWidth, maskHeight, domWidth, domHeight;
            //mask顯隐效果互動
            //一個會觸發冒泡,一個不會觸發冒泡且隻執行一次
            //滑鼠移出mouseover(冒泡多次執行),mouseout   滑鼠移入mouseenter,mouseleave
            // bindEvent(dom, 'mouseover', function (e) {
            //     console.log(e.target);
            // })
            var pos = offset(dom);
            function demo(e) {
                // //如果用mousemouve且位置擷取為offset的話,(如果擷取位置用client則無此問題)
                // //它會冒泡,即每次移動,mask都會複原到初始位置 ,是以需要阻止冒泡;
                //   e.stopPropagation();
                // //經測試,阻止冒泡後,仍mask會歸位再移到指定位置,不是該原因,(該知識點?√×)
                // 滑鼠位置的offset因為是在大盒子和mask中,它會擷取這兩個的位置,
                // 并都會執行,由于大盒子位置是固定的,是以mask會閃現到初始位置
                // 又因為擷取了滑鼠在mask中的位置,它會閃現到正确的位置
                //注意:由于使用client擷取位置,擷取的是頁面中的位置
                //      而圖檔往往不在頁面的左上角,會出現偏移量
                //      是以,需要對滑鼠的位置校正,(即可以把圖檔位置減到左上角就行計算)
                //e.client - offset(dom)  offset為封裝的函數(擷取定位元素(的左上角)在頁面中的位置)

                //滑鼠的位置就是 mask 的位置(mask的中心點)
                //擷取滑鼠位置
                //
                var x = e.clientX - pos.left;
                var y = e.clientY - pos.top;
                // console.log(x, y);
                //将中心點位置換算到頂點位置,mask的基準位置就是左上角的頂點位置
                x -= width / 4;//x=x-w/4
                y -= height / 4;
                //邊界處理
                if (x < 0) {
                    x = 0
                    //優化 } else if (x + width / 2 > width) {
                } else if (x > width / 2) {
                    //超出右邊框
                    x = width / 2;
                }
                if (y < 0) {
                    y = 0
                } else if (y > height / 2) {
                    y = height / 2;
                }
                //設定樣式
                css(mask, {
                    left: x + 'px',
                    top: y + 'px'
                })
                //設定大盒子圖檔的移動
                css(big, {
                    backgroundPositionX: x * -2 + 'px',
                    backgroundPositionY: y * -2 + 'px'
                })
            }
            bindEvent(dom, 'mouseenter', function (e) {
                // console.log(e.target);
                //顯示遮罩層
                css(mask, 'display', 'block')
                css(big, 'display', 'block')
                //直接綁定滑鼠移動事件
                bindEvent(dom, 'mousemove', demo)
            })
            bindEvent(dom, 'mouseleave', function (e) {
                // console.log(e.target);
                //顯示遮罩層
                css(mask, 'display', 'none')
                css(big, 'display', 'none')
                //删除事件
                removeEvent(document, 'mousemove', demo)
            })
        }
    </script>
</body>

</html>
           

自用庫引用部分 :

//bindEvent
// dom:元素  type:事件類型 fn:事件回調函數
//都在冒泡階段觸發

function bindEvent(dom, type, fn) {
    // 能力檢測,判斷方法是否存在,存在則使用,不存在則不使用
    if (dom.addEventListener) {
        //使用dom2級 綁定方式,都在冒泡階段觸發
        dom.addEventListener(type, fn)
    } else if (dom.attachEvent) {
        //在IE浏覽器環境中綁定事件,需要是 on +事件
        dom.attachEvent('on' + type, function (e) {
            //兼任性
            e.target = e.srcElement;
            e.currentTarget = this;
            fn.call(dom, e)//此處dom更改this對象為dom
        })
    } else {
        // 緩存
        var oldFn = dom['on' + type];
        //最原始的 dom0級 
        dom['on' + type] = function (e) {
            //如果已經綁定過相同僚件,則先執行緩存(已經綁定過的事件)
            oldFn && oldFn(e || window.event);
            //再執行新的
            fn(e || window.event);
        }
    }
}
//removeEvent(dom, eventName, demo)
// dom:對象;eventName事件名;demo函數
// 移除事件,封裝
function removeEvent(dom, type, fn) {
    if (dom.detachEvent) {
        //IE
        dom.detachEvent("on" + type, function () {
            fn.call(dom)
        })//此處使用回調函數call(),讓this指向dom 
    } else if (dom.removeEventListener) {
        //DOM2
        dom.removeEventListener(type, fn, false);
    } else {
        //dom0
        dom['on' + type] = null;
    }
}

//function offset(dom)//dom元素
//擷取定位元素在頁面中的位置
function offset(dom) {
    // console.log(dom.offsetParent, dom.offsetNode);
    //擷取目前元素的定位值
    var result = {
        left: dom.offsetLeft,
        top: dom.offsetTop
    };
    // console.log(result);//{left: 300, top: 200}
    //依次周遊每一個元素的定位元素,直到body
    while (dom.offsetParent) {
        //擷取目前元素的定位元素
        dom = dom.offsetParent;
        //累加結果
        //在進階浏覽器下,dom.offsetLeft不包括邊框
        // console.log(dom.offsetLeft, 111, result.left, 222, dom);
        result.left += dom.offsetLeft + dom.clientLeft;
        result.top += dom.offsetTop + dom.clientTop;
        //如果有兼任性問題,闊以适配
    }
    //傳回結果
    return result;
}
//封裝一個設定樣式的方法
//兩種用法:css(dom,width,'200px')
//         css(dom,{color:'red',width:'200px'})
function css(dom, key, value) {
    //判斷 key 是對象or字元串
    if (typeof key === 'string') {
        //說明是第一種使用方式,設定樣式;
        dom.style[key] = value;
    } else {
        //周遊每組樣式
        for (var name in key) {
            //name表示屬性名稱,key[name]表示樣式值
            css(dom, name, key[name])
        }
    }
}
           

繼續閱讀