放大镜特效是电商网站常用效果,指鼠标滑过图片时会出现图片的局部放大图,使用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