原生js實現放大鏡


效果:

1、  鼠標放上去會有半透明遮罩、右邊會有大圖片局部圖

2、  鼠標移動時右邊的大圖片也會局部移動

放大鏡的關鍵原理:

鼠標在小圖片上移動時,通過捕捉鼠標在小圖片上的位置,定位大圖片的相應位置;

放大鏡的移動方向和大圖片的移動方向:橫向和縱向都是相反,才可以保證同步;

 

頁面元素:

技術點:事件捕獲,定位

難點:計算

 

需要元素:小圖片和大圖片,存放小圖片和大圖片的容器,有一個放大鏡;

涉及到的技術點:

(1)       鼠標事件的捕獲:onmouseover(進入)、onmouseout(移除)、onmousemove(移動)

(2)       offsetLeft、offsetTop、offsetWidth、offsetHeight、event.clientX、event.clientY

  • offsetLeft子元素相對於父元素的左位移
  • offsetWidth,offsetHeight一個元素的寬度和高度,寬度和高度是不包括滾動條的。

event.clientX、event.clientY鼠標的X軸和Y軸,相對於整個頁面的坐標,而不是子元素

 

  • offsetLeft和style.left對比:

(1)、style.left返回的是字符串,如30px、offsetLeft返回的是數值30;

(2)、style.left是可讀寫的,offsetLeft是只讀的,所以要改變div的位置,只能修改style.left;

(3)、style.left的值需要事先定義,否則取到的值為空。

style.left只針對在HTML中寫的值有效,樣式表中無法定義style.left;

制作放大鏡所需要的計算

》重點:如何讓小圖片上的放大鏡和大圖片同步移動

關鍵:小圖片的比例和大圖片的比例是一樣的,放大鏡比例和右側大的容器比例是一樣的;他們之間的比例是相同的

移動時的比例計算:

放大鏡核心計算公式:

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>放大鏡</title>
    <style>
        * {
            margin: 0;
            padding: 0
        }
        #demo {
            display: block;
            width: 323px;
            height: 430px;
            margin: 5px;
            position: relative;
            border: 1px solid #ccc;
        }
        #small-box {
            position: relative;
            z-index: 1;
        }
        #float-box {
            display: none;
            width: 160px;
            height: 120px;
            position: absolute;/*使元素脫離文檔流,方便自由操控元素*/
            background: #ffffcc;
            border: 1px solid #ccc;
            filter: alpha(opacity=50);
            opacity: 0.5;
        }
        #mark {/*應該是把圖片放在這個上面,它的透明度為0,是個block*/
            position: absolute; /*元素脫離文檔流,使得圖片和浮動框可與之重疊,也正因如此,要↓*/
            display: block;                                                       ↓
            width: 323px;                                                         ↓                 
            height: 430px;                                                        ↓
            background-color: #fff;                                               ↓
            filter: alpha(opacity=0);/*過濾器,目前只有少數瀏覽器支持*/                ↓
            opacity: 0;                                                           ↓
            z-index: 10;/*確保markBox位於floatBox和圖片之上,防止markBox被覆蓋,導致對markBox的鼠標移動事件不起作用*/
        }
        #big-box {
            display: none;
            position: absolute;
            top: 0;
            left: 330px;
            width: 400px;
            height: 300px;
            overflow: hidden;
            border: 1px solid #ccc;
            z-index: 1;
        }

        #big-box img {
            position: absolute;
            z-index: 5
        }
    </style>
    <script>

        //頁面加載完畢后執行
        window.onload = function () {
            //找六個個元素:demo,smallBox,foatBox,mark,bigfloatBox,imgs,
            var objDemo=document.getElementById("demo");
            var objSmallBox=document.getElementById("small-box");
            var objMarkBox=document.getElementById("mark");
            var objFloatBox=document.getElementById("float-box");
            var objBigBox=document.getElementById("big-box");
            var objBigBoxImg=objBigBox.getElementsByTagName("img")[0];

            //給小盒子添加事件,移入和移出
            //移入:浮動的box和和bigBox顯示
            objSmallBox.onmouseover=function(){
                objFloatBox.style.display="block";
                objBigBox.style.display="block";
            }
            //移除:浮動的box和bigBox隱藏
            objSmallBox.onmouseout=function(){
                objFloatBox.style.display="none";
                objBigBox.style.display="none";
            }

            //給小盒子添加鼠標移動事件
            objMarkBox.onmousemove=function(ev){
                var _event=ev||window.event;//做兼容性,兼容IE
                //1計算值:
                var left=_event.clientX-objDemo.offsetLeft-objSmallBox.offsetLeft-objFloatBox.offsetWidth/2;
                var top=_event.clientY-objDemo.offsetTop-objSmallBox.offsetTop-objFloatBox.offsetHeight/2;

                //5.優化,在前面加判斷,不讓其溢出,加判斷
                if(left<0) left=0;
                if(top<0) top=0;
                if(left>objSmallBox.offsetWidth-objFloatBox.offsetWidth)
                        left=objSmallBox.offsetWidth-objFloatBox.offsetWidth;
                if(top>objSmallBox.offsetHeight-objFloatBox.offsetHeight)
                        top=objSmallBox.offsetHeight-objFloatBox.offsetHeight;

                //2把值賦值給放大鏡
                objFloatBox.style.left=left+"px";
                objFloatBox.style.top=top+"px";

                //3計算比例
                var percentX=left/(objMarkBox.offsetWidth-objFloatBox.offsetWidth);
                var percentY=top/(objMarkBox.offsetHeight-objFloatBox.offsetHeight);

                //4利用這個比例計算距離后賦值給右側的圖片
                objBigBoxImg.style.left=-percentX*(objBigBoxImg.offsetWidth-objBigBox.offsetWidth)+"px";
                objBigBoxImg.style.top=-percentY*(objBigBoxImg.offsetHeight-objBigBox.offsetHeight)+"px";
            }

        }
    </script>
</head>
<body>
<div id="demo">
    <div id="small-box">
        <div id="mark"></div>
        <div id="float-box"></div>
        <img src="https://img.alicdn.com/imgextra/https://img.alicdn.com/bao/uploaded/i2/1026430696/O1CN011H0o7UD6ZwLT3vl_!!1026430696.jpg_430x430q90.jpg"/>
    </div>
    <div id="big-box">
        <img src="https://img.alicdn.com/imgextra/https://img.alicdn.com/bao/uploaded/i2/1026430696/O1CN011H0o7UD6ZwLT3vl_!!1026430696.jpg"/>
    </div>
</div>
</body>
</html>

 個人感覺MarkBox是多余的操作,於是我將上述代碼中與markBox相關的操作去掉,如下:

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>放大鏡</title>
    <style>
        * {
            margin: 0;
            padding: 0
        }
        #demo {
            display: block;
            width: 323px;
            height: 430px;
            margin: 5px;
            position: relative;
            border: 1px solid #ccc;
        }
        #small-box {
            position: relative;
            z-index: 1;
        }
        #float-box {
            display: none;
            width: 160px;
            height: 120px;
            position: absolute;
            background: #ffffcc;
            border: 1px solid #ccc;
            filter: alpha(opacity=50);
            opacity: 0.5;    
        }
        #big-box {
            display: none;
            position: absolute;
            top: 0;
            left: 330px;
            width: 323px;
            height: 430px;
            overflow: hidden;
            border: 1px solid #ccc;
            z-index: 10;
        }
        #big-box img {
            position: absolute;
            z-index: 5
        }
    </style>
    <script>
        //頁面加載完畢后執行
        window.onload = function () {
            //找五個個元素:demo,smallBox,foatBox,bigfloatBox,imgs,
            var objDemo=document.getElementById("demo");
            var objSmallBox=document.getElementById("small-box");
            var objFloatBox=document.getElementById("float-box");
            var objBigBox=document.getElementById("big-box");
            var objBigBoxImg=objBigBox.getElementsByTagName("img")[0];

            //給小盒子添加事件,移入和移出
            //移入:浮動的box和和bigBox顯示
            objSmallBox.onmouseover=function(){
                objFloatBox.style.display="block";
                objBigBox.style.display="block";
            }
            //移除:浮動的box和bigBox隱藏
            objSmallBox.onmouseout=function(){
                objFloatBox.style.display="none";
                objBigBox.style.display="none";
            }

            //給小盒子添加鼠標移動事件
             objSmallBox.onmousemove=function(ev){
                var _event=ev||window.event;//做兼容性,兼容IE
                //1計算值:
                var left=_event.clientX-objDemo.offsetLeft-objSmallBox.offsetLeft-objFloatBox.offsetWidth/2;
                var top=_event.clientY-objDemo.offsetTop-objSmallBox.offsetTop-objFloatBox.offsetHeight/2;

                //5.優化,在前面加判斷,不讓其溢出,加判斷
                if(left<0) left=0;
                if(top<0) top=0;
                if(left>objSmallBox.offsetWidth-objFloatBox.offsetWidth)
                        left=objSmallBox.offsetWidth-objFloatBox.offsetWidth;
                if(top>objSmallBox.offsetHeight-objFloatBox.offsetHeight)
                        top=objSmallBox.offsetHeight-objFloatBox.offsetHeight;

                //2把值賦值給放大鏡
                objFloatBox.style.left=left+"px";
                objFloatBox.style.top=top+"px";

                //3計算比例
                var percentX=left/( objSmallBox.offsetWidth-objFloatBox.offsetWidth);
                var percentY=top/( objSmallBox.offsetHeight-objFloatBox.offsetHeight);

                //4利用這個比例計算距離后賦值給右側的圖片
                objBigBoxImg.style.left=-percentX*(objBigBoxImg.offsetWidth-objBigBox.offsetWidth)+"px";
                objBigBoxImg.style.top=-percentY*(objBigBoxImg.offsetHeight-objBigBox.offsetHeight)+"px";
            }

        }
    </script>
</head>
<body>
<div id="demo">
    <div id="small-box">
        <div id="float-box"></div>
        <img src="https://img.alicdn.com/imgextra/https://img.alicdn.com/bao/uploaded/i2/1026430696/O1CN011H0o7UD6ZwLT3vl_!!1026430696.jpg_430x430q90.jpg"/>
    </div>
    <div id="big-box">
        <img src="https://img.alicdn.com/imgextra/https://img.alicdn.com/bao/uploaded/i2/1026430696/O1CN011H0o7UD6ZwLT3vl_!!1026430696.jpg"/>
    </div>
</div>
</body>
</html>
View Code

 運行效果相同


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM