用JS逐步分解實現放大鏡(看完就有收穫)

案例描述

在瀏覽器的左邊有一張大圖,下面有兩張小圖,點擊任何一張小圖會在大圖的位置顯示這張小圖的畫面。進入大圖,鼠標所指之處有一個透明的黃色區域,而在大圖的右邊(以下稱超大圖)會放大這一區域

案例圖示

在這裏插入圖片描述

HTML

<body>
    <div id="box">
        <div id="small">
            <img src="./program1/images/1.jpg" >
            <span id="mask"></span>
        </div>
        <div id="big">
            <img src="./program1/images/1.jpg" >
        </div>
    </div>
    <div id="list">
        <ul>
            <li><img src="./program1/images/1.jpg" width="100px"></li>
            <li><img src="./program1/images/2.jpg" width="100px"></li>
        </ul>
    </div>
</body>

CSS樣式

詳解請看註釋

<style>
    * {
        padding: 0;
        margin: 0;
        box-sizing: border-box;
        list-style: none;
        border: none;
    }
    #box {
        width: 250px;
        height: 160px;
        margin-left: 100px;
        margin-top: 100px;
        position: relative;
    }
    #small {
        width: 100%;
        height: 100%;
        border: 1px solid #ccc; 
        /* 放大鏡操作 */
        position: relative;       
    }
    #small img{
        width: 100%;
        height: 100%;
        padding: 2px;

    }
    /* 顯微鏡 */
    #mask {
        width: 50px;
        height: 50px;
        /* 透明圖 */
        background-color:rgba(255, 255, 0,.4);
        position: absolute;
        left: 0;
        top: 0;
        cursor: move;
        /* 隱藏 */
        display: none;
    }
    #big {
        width: 400px;
        height: 255px;
        border: 1px solid #ccc;
        /* 爲以後大圖位置改變作準備 */
        position: absolute;
        /* 250 + 10 margin */
        left: 260px;     
        top: 0;
        /* 圖片超出部分隱藏 */
        overflow: hidden;
        /* 整個大圖開始是隱藏的 */
        display: none;
    }
    #big img {
        width: 700px;
        padding: 2px;
        position: absolute;
        left: 0;
        top: 0;
        margin: 0 auto;
        background-color: red;
    }
    #list {
        margin-top: 5px;
        margin-left: 100px;
    }
    #list li {
        float: left;
        margin-right: 5px;
        cursor: pointer;
    }
</style>

JS代碼

JS分解代碼----小圖點擊事件

(1)首先設置一個value屬性用於改變small_img中的圖片src,value的值爲其下標+1
(2)監聽li中的點擊事件時,要改變small_img(大圖)中的圖片展示和big_img(超大圖)中的圖片展示

 for (let i = 0; i < allLi.length; i++) {
            var li = allLi[i];
            //設置一個value屬性用於改變small_img中的圖片src
            li.setAttribute('value',i+1);
            //監聽li中的點擊事件
            li.addEventListener('click',function(){
                //改變small_img中的圖片展示
                small_img.setAttribute('src',"./program1/images/" + this.getAttribute('value') +".jpg");
                //改變big_img中的圖片展示
                big_img.setAttribute('src',"./program1/images/" + this.getAttribute('value') +".jpg");
            });
        }

JS分解代碼----鼠標進入和移出

鼠標進入和移出都要改變放大鏡和超大圖的display屬性。
進入時display屬性值爲*“block”*
移出時display屬性值爲*“none”*

//監聽鼠標進入box
        box.addEventListener('mouseover',function() { 
            //放大鏡顯示
            mask.style.display = 'block';
            //big圖片顯示
            big.style.display = 'block';       
        });

        //監聽鼠標移出box
        box.addEventListener('mouseout',function(){
            //放大鏡隱藏
            mask.style.display = 'none';
            //big圖片隱藏
            big.style.display = 'none';
        })
    });

JS分解代碼----鼠標的移動

在鼠標進入事件中監聽鼠標的移動
這裏運用到事件對象和offset家族的知識
可以參考:
事件對象
offset家族
注意事項看註釋

 //監聽鼠標的移動
small.addEventListener('mousemove',function(event){
//事件對象
var e = event || window.event;
//獲取鼠標的位置  鼠標顯示在mask中間:減去自身寬高度的一半
//最好用pageX、pageY,不要用clientX、clientY 防止有分頁時出錯
 var small_x = event.pageX - box.offsetLeft - mask.offsetWidth*0.5;
var small_y= event.pageY - box.offsetTop - mask.offsetHeight*0.5;

JS分解代碼----碰撞事件,放大鏡的移動

寫完上述代碼,你會發現放大鏡也能去到大圖以外的區域,這不是我們所期望的,這裏就需要用到碰撞事件了
這裏還是用到了offset家族的知識
這裏用到的思維是用if判斷條件限制上下左右的邊界
放大鏡的移動就是改變它的top和left值(因爲它相對父元素絕對定位)
不理解offset,請參考:offset家族
注意事項看註釋


//放大鏡碰撞    

//相對於box  因爲box有定位
if(small_x <= 0)
	small_x = 0;
else if( small_x >= box.offsetWidth-mask.offsetWidth)
	small_x = box.offsetWidth-mask.offsetWidth - 2;   //除去邊框
if(small_y <= 0)
	small_y = 0;
else if( small_y >= box.offsetHeight-mask.offsetHeight)
	small_y = box.offsetHeight-mask.offsetHeight - 2;

//放大鏡跟着鼠標的位置 
mask.style.left = small_x + 'px';
mask.style.top = small_y + 'px';
               

JS分解代碼----超大圖的位置改變

big_img.style.leftbig_img.style.top爲負值(你可以試試去掉負號是什麼樣的效果)
這裏的重點是這個公式

 //big_img中的位置相應改變
//公式:small_x/big_x = small_width/big_img_width
               
big_img.style.left = - (event.pageX - box.offsetLeft) /(small.offsetWidth / big.offsetWidth) + 'px';
big_img.style.top = -( event.pageY - box.offsetTop)/( small.offsetHeight / big.offsetHeight) + 'px';

JS全部代碼展示

<script>
    window.addEventListener ('load',function(){
        //獲取元素
        var small = $('small');
        var big = $('big');   
        var mask = $('mask');
        var allLi = document.getElementsByTagName('li');
        var small_img = small.children[0];
        var big_img = big.children[0];

        //遍歷每一個li中的點擊事件
        for (let i = 0; i < allLi.length; i++) {
            var li = allLi[i];
            //設置一個value屬性用於改變small_img中的圖片src
            li.setAttribute('value',i+1);
            //監聽li中的點擊事件
            li.addEventListener('click',function(){
                //改變small_img中的圖片展示
                small_img.setAttribute('src',"./program1/images/" + this.getAttribute('value') +".jpg");
                //改變big_img中的圖片展示
                big_img.setAttribute('src',"./program1/images/" + this.getAttribute('value') +".jpg");
            });
        }

        //監聽鼠標進入box
        box.addEventListener('mouseover',function() { 
            //放大鏡顯示
            mask.style.display = 'block';
            //big圖片顯示
            big.style.display = 'block';

            //監聽鼠標的移動
            small.addEventListener('mousemove',function(event){
                //事件對象
                var e = event || window.event;
                //獲取鼠標的位置  鼠標顯示在mask中間:減去自身寬高度的一半
                //最好用pageX、pageY,不要用clientX、clientY 防止有分頁時出錯
                var small_x = event.pageX - box.offsetLeft - mask.offsetWidth*0.5;
                var small_y= event.pageY - box.offsetTop - mask.offsetHeight*0.5;


                //放大鏡碰撞    
                // console.log(mask.offsetLeft) ;
                //相對於box  因爲boxx有定位
                if(small_x <= 0)
                    small_x = 0;
                else if( small_x >= box.offsetWidth-mask.offsetWidth)
                    small_x = box.offsetWidth-mask.offsetWidth - 2;   //除去邊框
                if(small_y <= 0)
                    small_y = 0;
                else if( small_y >= box.offsetHeight-mask.offsetHeight)
                    small_y = box.offsetHeight-mask.offsetHeight - 2;

                 //放大鏡跟着鼠標的位置 
                mask.style.left = small_x + 'px';
                mask.style.top = small_y + 'px';
               
               //big_img中的位置相應改變
               //公式:small_x/big_x = small_width/big_img_width
               
                big_img.style.left = - (event.pageX - box.offsetLeft) /(small.offsetWidth / big.offsetWidth) + 'px';
                big_img.style.top = -( event.pageY - box.offsetTop)/( small.offsetHeight / big.offsetHeight) + 'px';


            });
           
        });

        //監聽鼠標移出box
        box.addEventListener('mouseout',function(){
            //放大鏡隱藏
            mask.style.display = 'none';
            //big圖片隱藏
            big.style.display = 'none';
        })
    });

    //封裝
    function $(id) {
        return typeof id === 'string'? document.getElementById(id):null;
    }
</script>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章