放大镜特效是电商网站常用效果,指鼠标滑过图片时会出现图片的局部放大图,使用JS就可实现,下面是最终效果图:
放大镜原理:
鼠标在小图片上移动时,通过捕获鼠标在小图标上的位置,定位大图标相应的位置主要功能:
鼠标移入,放大镜显示鼠标移出,放大镜隐藏
鼠标移动,放大镜随之移动,并且当大制定部分
涉及三个鼠标事件:
onmouseover : 鼠标指针移动到指定对象时触发onmouseout: 鼠标指针移出指定对象时触发
onmouseomove: 鼠标指针移动时触发
技术点:
offsetLeft: 子元素相对父元素的左位移offsetTop:子元素相对父元素的上位移
offsetWidth:元素自身宽度
offsetHeight:元素自身高度
event.clientX:鼠标X轴坐标,相对整个页面
event.clientY:鼠标Y轴坐标,相对整个页面
核心算法:
核心算法计算难点是如何让让小图片上的放大镜和大图片同时移动。
如下图所示: 小图片放大成大图片,放大镜和大图片局部 ,二者比例相等。
假设 : 小图片度为A,大图片度为B
当放大镜向右移动一定距离X ,则大图片应当向左移动Y,则 X/Y = A/B
下面是源码:
HTML CSS:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>JS实现放大镜功能</title> <style type="text/css"> * { margin: 0; padding: 0; } #demo { display: block; width: 400px; height: 255px; margin: 50px; position: relative; border: 1px solid #ccc; } #small-box { position: relative; } #big-box { display: none; position: absolute; top: 0; left: 460px; width: 400px; height: 300px; overflow: hidden; border: 1px #ccc solid; z-index: 1; } #float-box { display: none; width: 160px; height: 120px; position: absolute; background: #ffffcc; border: 1px solid #ccc; opacity: .5; filter: alpha(opacity=50); } #mark { position: absolute; display: block; width: 400px; height: 255px; background-color: #fff; filter: alpha(opacity=0); opacity: 0; z-index: 10; } #big-box img { position: absolute; z-index: 5 } </style> </head> <body> <div id="demo"> <!-- 小图片 --> <div id="small-box"> <!-- 遮罩层 解决IE兼容问题 --> <div id="mark"></div> <!-- 放大镜 --> <div id="float-box"></div> <!-- 图片 --> <img src="macbook-small.jpg"/> </div> <!-- 大图片 --> <div id="big-box"> <img src="macbook-big.jpg"/> </div> </div> <script type="text/javascript" src="script.js"></script> </body> </html>
JS:
window.onload = function(){ // 获取元素 var objDemo = document.getElementById("demo"); var objSmallBox = document.getElementById('small-box'); var objFloatBox = document.getElementById('float-box'); var objBigBox = document.getElementById('big-box'); var objMark = document.getElementById("mark"); var objBigBoxImage = objBigBox.getElementsByTagName("img")[0]; objSmallBox.onmouseover = function(){ objFloatBox.style.display = 'block'; objBigBox.style.display = 'block'; } objSmallBox.onmouseout = function(){ objFloatBox.style.display = 'none'; objBigBox.style.display = 'none'; } objSmallBox.onmousemove = function(ev){ var _event = ev || window.event; //兼容多个浏览器的event参数模式 var left = _event.clientX - objDemo.offsetLeft - objSmallBox.offsetLeft - objFloatBox.offsetWidth / 2; var top = _event.clientY - objDemo.offsetTop - objSmallBox.offsetTop - objFloatBox.offsetHeight / 2; if (left < 0) { left = 0; } else if (left > (objMark.offsetWidth - objFloatBox.offsetWidth)) { left = objMark.offsetWidth - objFloatBox.offsetWidth; } if (top < 0) { top = 0; } else if (top > (objMark.offsetHeight - objFloatBox.offsetHeight)) { top = objMark.offsetHeight - objFloatBox.offsetHeight; } objFloatBox.style.left = left + "px"; //oSmall.offsetLeft的值是相对什么而言 objFloatBox.style.top = top + "px"; var percentX = left / (objMark.offsetWidth - objFloatBox.offsetWidth); var percentY = top / (objMark.offsetHeight - objFloatBox.offsetHeight); objBigBoxImage.style.left = -percentX * (objBigBoxImage.offsetWidth - objBigBox.offsetWidth) + "px"; objBigBoxImage.style.top = -percentY * (objBigBoxImage.offsetHeight - objBigBox.offsetHeight) + "px"; } }
IE浏览器兼容性问题解决:
1.更改事件捕获写法
var _event = ev || window.event;
2.在图片 img 和放大镜 float-box 之间添加一个透明遮罩层 mark,并且将鼠标事件绑定在遮罩层上,
以避免鼠标移动频繁触发mouseout 和 mouseover 造成图片闪烁问题
原课程地址:https://www.imooc.com/learn/32