效果:
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>
運行效果相同