分析
- 与模态框案例一致,先获取鼠标的坐标和鼠标在盒子内的坐标
- 实现半透明mask的中心,即正方形的宽度高度的一半跟随鼠标移动
- 限制半透明mask只能在preview-img的范围内移动
- 使用offsetWidth和offsetHeight获取preview-img和mask的宽度,用来判断是否超出
- 当mask.offsetWidth/Height超出preview-img.offsetWidth/Height的范围时,则停止mask的移动
代码
<!DOCTYPE html>
<html lang="ZH-cn">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
}
body {
display: block;
overflow: scroll;
}
li {
list-style: none;
}
img {
vertical-align: middle;
}
.fl {
float: left;
}
.fr {
float: right;
}
.top-list {
background-color: #cfcfcf;
height: 20px;
}
.top-list li{
list-style: none;
margin-left: 5px;
font-size: 12px;
}
.top-list li a {
text-decoration: none;
color: #333;
}
.reg ul li{
float: left;
}
.right ul li{
float: right;
}
.w {
width: 1200px;
margin: 0 auto;
}
.container {
margin-top: 20px;
}
.product {
float: left;
margin-top: 80px;
}
.preview {
width: 400px;
height: 590px;
}
.preview-img {
position: relative;
height: 398px;
border: 1px solid #ccc;
}
.mask {
display: none;
position: absolute;
left: 0;
top: 0;
width: 300px;
height: 300px;
background-color: blue;
opacity: .5;
border: 1px solid #ccc;
cursor: move;
}
.big {
display: none;
position: absolute;
left: 410px;
top: 0;
width: 500px;
height: 500px;
background-color: pink;
z-index: 999;
border: 1px solid #ccc;
overflow: hidden;
}
.big img {
position: absolute;
top: 0;
left: 0;
}
.preview-img>img {
height: 398px;
}
.preview-list {
position: relative;
height: 60px;
margin-top: 60px;
}
.arrow-prev {
left: 0;
background: url(./arrow-prev.png);
}
.arrow-next {
right: 0;
background: url(./arrow-next.png);
}
.arrow-prev,
.arrow-next {
position: absolute;
width: 22px;
height: 32px;
}
.list-item {
width: 320px;
height: 60px;
margin: 0 auto;
}
.list-item li {
float: left;
width: 56px;
height: 56px;
border: 2px solid transparent;
margin: 0 2px;
background-color: pink;
}
/*清除浮动*/
.clearfix:before,
.clearfix:after {
content: "";
display: table;
}
.clearfix:after {
clear: both;
}
.clearfix {
*zoom: 1;
}
</style>
</head>
<body>
<div class="top-list .clearfix:after">
<div class="reg">
<ul>
<li>欢迎您!</li>
<li>
<a href="javascript:;" class="log-li">登录</a>
<a href="javascript:;" class="reg-li">注册</a>
</li>
</ul>
</div>
<div class="right">
<ul>
<li>
<a href="javascript:;">我的订单</a>
</li>
<li>
<a href="javascript:;">会员中心</a>
</li>
</ul>
</div>
</div>
<div class="container w">
<div class="product clearfix">
<div class="preview fl">
<div class="preview-img">
<img src="./05-京东放大镜效果/upload/b3.png" alt="">
<div class="mask"></div>
<div class="big">
<img src="./05-京东放大镜效果/upload/big.jpg" alt="" class="bigImg">
</div>
</div>
<div class="preview-list">
<a href="#" class="arrow-prev"></a>
<a href="#" class="arrow-next"></a>
<ul class="list-item">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</div>
</div>
</div>
</div>
<script>
var mask = document.querySelector('.mask');
var big = document.querySelector('.big');
var img = document.querySelector('.preview-img');
var bigImg = document.querySelector('.bigImg');
img.addEventListener('mouseover', function () {
mask.style.display = 'block';
big.style.display = 'block'
})
img.addEventListener('mousemove', function (e) {
/*149 247*/
var x = e.pageX - img.offsetLeft;
var y = e.pageY - img.offsetTop;
var maskX = x - mask.offsetWidth / 2;
var maskY = y - mask.offsetHeight / 2;
var maskMax = img.offsetWidth - mask.offsetWidth;
if(maskX <= 0) {
maskX = 0;
}else if(maskX >= maskMax) {
maskX = maskMax;
}
if(maskY <= 0) {
maskY = 0;
}else if(maskY >= maskMax) {
maskY = maskMax;
}
mask.style.left = maskX + 'px';
mask.style.top = maskY + 'px';
var bigMax = bigImg.offsetWidth - big.offsetWidth;
var bigX = maskX * bigMax / maskMax;
var bigY = maskY * bigMax / maskMax;
bigImg.style.left = -bigX + 'px';
bigImg.style.top = -bigY + 'px';
})
img.addEventListener('mouseout', function () {
mask.style.display = 'none';
big.style.display = 'none';
})
</script>
</body>
</html>
因为mask是正方形形状的div盒子,所以maskMax使用offsetWidth计算出来的值也适用于offsetHeight,maskMax为mask能够向下和向右移动的最大距离,即与left和top的坐标的最大值
在mask进行移动的时候,也将移动的值按比例的负值给big大图片的移动距离中,使得big图片能够与mask的移动方向完全相反,实现放大镜的效果