放大镜案例
案例分析:
1,整个案例可以分为三个功能模块
2,鼠标经过小图片盒子,黄色的遮挡层 和 大图片盒子显示,鼠标离开,两个盒子隐藏
3,黄色的遮挡层跟随鼠标功能
4,移动黄色遮挡层,大图片跟随移动功能
关键代码:
①布局:
把big 定位在demo 里面,demo 里面放一个 small(和demo一样大) , 图片直接放在 samll 里面而 不是直接放在demo 里面,另外 , 黄色盒子放在small里面也不是放在demo里面。
之所以在demo里面放一个small ,是因为 big 通过绝对定位放在demo里面,如果鼠标图片直接 放在demo里面,那么如果鼠标经过demo,big 会显示,鼠标离开demo,big应该要隐藏,但是经 测试,鼠标离开demo的时候 big并没有隐藏,因为big也在demo里面
黄色遮挡层如果不放在small里面,鼠标经过small的时候,big快速闪烁,不会正常显示,这是因 为黄色遮挡层独立于small, 鼠标经过的地方是samll但也是黄色遮挡层,那么big又会隐藏,所以 big会跳动闪烁,因此黄色遮挡层必须放在small里面。
可以测试以下:
demo.onmousover=function(){ mask.style.display="block"; big.style.display="block"; } demo.onmouseout=function() { mask.style.display="none"; big.style.display="none"; }
所以这样布局更加恰当
<div id="demo"> <div id="small"> <img src=images/001.jpg"> <div id="mask"></div> </div> <div id="big"> <img src="images/0001.jpg"> </div> </div>
②鼠标经过小图片盒子,黄色的遮挡层 和 大图片盒子显示,鼠标离开,两个盒子隐藏
small.onmouseover=function(){ mask.style.diaplay="block"; big.style.display="block"; } small.onmouseout=function(){ mask.style.display="none"; big.style.display="none"; }
③黄色遮挡层跟随鼠标功能
a 直接把鼠标坐标给遮挡层不合适,因为遮挡层的坐标是以父盒子为准的。
b 首先是获得鼠标在盒子的坐标
c 之后把数值给遮挡层作为遮挡层的 left 和 top 值
d 此时用到鼠标移动事件,但是还是在小图片盒子内移动
e 发现遮挡层位置不对,需要再减去盒子自身高度和宽度的一半
f 遮挡层不能超出小图片盒子范围,让遮挡层卡在小图片盒子里面:
g 如果遮挡层 left 小于0,就把坐标设置为0
h 如果遮挡层大于最大移动距离,就把坐标设置为最大的移动距离
i 遮挡层的最大移动距离:小图片盒子宽度 - 遮挡层盒子宽度;
小图片盒子高度 - 遮挡层盒子高度
j 求大图片移动距离公式:
遮挡层移动距离 / 遮挡层最大移动距离 = 大图片移动距离 / 大图片最大移动距离
small.onmousemove=function(e){ var x=e.pageX - demo.offsetLeft - mask.offsetWidth/2; // 用 demo 的 offsetLeft, 不用this或 small 的 offsetLeft 值,demo是相对定位的,另外,为了让鼠标在mask的正中间,需要 mask 向上向左移动自身高度/宽度的一半 var y=e.pageY - demo.offsetTop - mask.offsetTop /2 ; if(x <=0 ) { x=0; } else if (x >= small.offsetWidth-mask.offsetWidth){ x = small.offsetWidth - mask.offsetWidth; } if ( y<=0) { y=0; } else if ( y >= small.offsetTop - mask.offsetTop){ y = small.offsetTop - mask.offsetTop ; } mask.style.left = x + "px"; mask.style.top = y +"px"; }
大图片跟随移动:
注意,大图片盒子和mask黄色遮挡层的移动方向相反,要加 负号
big.style.left = -x * (big.offsetWidth / small. offsetWidth) +"px"; big.style.top = -y *(big.offsetHeight / small.offsetHeight ) +"px";
完整代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> *{ padding:0; margin:0; } #demo{ width:350px; height:350px; border:1px solid black; margin:100px; position:relative; } #small{ position:absolute; left:0; top:0; } #big{ position:absolute; left:400px; top:0; width:450px; height:450px; overflow:hidden; border:1px solid black; display:none; } #small #mask{ width:100px; height:100px; background-color: lightyellow; position:absolute; top:0; left:0; display:none; cursor:move; } #big img{ position:absolute; top:0; left:0; } </style> </head> <body> <!--把big定位在demo里面,demo里面放一个small和demo一样大,鼠标图片放在small里面而不是直接放在demo里面,另外,黄色盒子放在small也不是放在demo里面--> <div id="demo"> <div id="small"> <img src="images/001.jpg" alt=""> <div id="mask"></div> </div> <div id="big"> <img src="images/0001.jpg" alt=""> </div> </div> </body> </html> <script> var demo=document.getElementById("demo"); var small=document.getElementById("small"); var big=document.getElementById("big"); var mask=document.getElementById("mask"); small.onmouseover=function() { //huang如果不放在small里面,鼠标经过small的时候,big快速闪烁,不会正常显示,这是因为huang独立于small,鼠标经过的地方是samll但也是huang,经过huang也是离开small,那么big又会隐藏,所以big会跳动闪烁,出了bug,因此,huang必须放在samll里面 big.style.display="block"; mask.style.display="block"; } small.onmouseout=function () { big.style.display="none"; mask.style.display="none"; } small.onmousemove=function(event) { var event = event || window.event; var x = event.clientX - this.offsetParent.offsetLeft - mask.offsetWidth / 2; //用small的offsetParent即demo的offsetLeft,不用this即small的offsetLeft值,demo是相对定位的,另外,为了让huang坐标在正中间,要向上向左走huang高度和宽度的一半 var y = event.clientY - this.offsetParent.offsetTop - mask.offsetHeight / 2; //if-else的判断是为了让mask限制在small内 if (x < 0) { x = 0; } else if (x > small.offsetWidth - mask.offsetWidth) { x = small.offsetWidth - mask.offsetWidth; } if (y < 0) { y = 0; } else if (y > small.offsetHeight - mask.offsetHeight) { y = small.offsetHeight - mask.offsetHeight; } mask.style.left = x + "px"; mask.style.top = y + "px"; var bigImage = big.children[0]; bigImage.style.left = -x * (big.offsetWidth / small.offsetWidth) + "px"; //small和big的移动方向相反,所以加负号 bigImage.style.top = -y * (big.offsetHeight / small.offsetHeight) + "px";//huang移动的距离*(big/small的倍数)=大盒子中图片的位置 } </script>