一、执行效果
二、代码结构
1. HTML CSS
class="preview"
的div里面放小图片、黄色遮罩层和大图片- 给黄色遮罩层和大图片
position: absolute;
,并定位至对应位置 - 大图片的div给固定宽高,图片超出部分
overflow: hidden;
cursor: move;
给黄色遮罩层一个鼠标看起来可移动的样式
2. js
-
获取对应元素,给
.preview
绑定鼠标移入和鼠标移出事件,分别对应显示遮罩层大图片与隐藏遮罩层大图片。 -
再给
.preview
绑定鼠标移动事件,根据鼠标距离页面的x和y值,减去.preview
距离页面的 offsetLeft 和 offsetTop 值算出鼠标在.preview
内的相对位置。这时如果直接把结果给遮罩层的 left 和 top 的话,会导致遮罩层的左上角定点和鼠标重合,不太符合鼠标位于遮罩层中心的要求,所以给鼠标相对位置减去遮罩层的宽高的一半,达到鼠标位于遮罩层中间的效果。 -
此时鼠标移动,遮罩层会超出
.preview
,此时根据下面公式计算可得:本题遮罩层最大可移动距离为400-300=100px
,当遮罩层移动距离大于.preview的宽(高) - 遮罩层自己的宽(高)
时,设置最大移动距离就等于.preview的宽(高) - 遮罩层自己的宽(高)
最小可移动距离为0,所以限制当遮罩层移动位置小于0时,设置移动距离为0
遮罩层的最大可移动距离 = . p r e v i e w 的宽(高) − 遮罩层自己的宽(高) 遮罩层的最大可移动距离 =.preview的宽(高) - 遮罩层自己的宽(高) 遮罩层的最大可移动距离=.preview的宽(高)−遮罩层自己的宽(高) -
大图片最大可移动距离计算同理。
-
最后根据易错点1所给公式对应出遮罩层移动距离和大图片移动距离的对照关系
三、易错点
-
根据比例来计算遮罩层的移动和大图片的移动对应关系,对应关系如下:
-
大图片移动距离 / 大图片最大可移动距离 = 遮罩层移动的距离 / 遮罩层最大移动距离 大图片移动距离/大图片最大可移动距离 = 遮罩层移动的距离 / 遮罩层最大移动距离 大图片移动距离/大图片最大可移动距离=遮罩层移动的距离/遮罩层最大移动距离
大图片移动距离 = 遮罩层移动的距离 ∗ 大图片最大可移动距离 / 遮罩层最大移动距离 大图片移动距离 = 遮罩层移动的距离 * 大图片最大可移动距离 / 遮罩层最大移动距离 大图片移动距离=遮罩层移动的距离∗大图片最大可移动距离/遮罩层最大移动距离
-
-
在最后根据遮罩层的移动而移动大图片的时候,一定要记得在css部分加上大图片自己的定位(
position: absolute; top: 0; left: 0;
)这样才能在移动的时候修改 top 和 left 值。 -
在script中给css的 top 和 left 属性赋值时一定记得加单位(px)
四、代码
<!DOCTYPE html>
<html lang="en">
<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>
* {
margin: 0;
padding: 0;
}
html {
height: 1200px;
}
.w {
width: 1200px;
margin: 0 auto;
}
.preview {
position: relative;
top: 100px;
height: 398px;
width: 398px;
border: 1px solid #ccc;
}
.mask {
display: none;
position: absolute;
top: 0;
left: 0;
width: 300px;
height: 300px;
background-color: #fede4f;
opacity: 0.5;
border: 1px solid #ccc;
cursor: move;
}
.big {
display: none;
overflow: hidden;
position: absolute;
left: 410px;
top: 0;
width: 500px;
height: 500px;
z-index: 999;
border: 1px solid #ccc;
}
.bigImg {
position: absolute;
top: 0;
left: 0;
}
</style>
</head>
<body>
<div class="w">
<div class="preview">
<img src="img/s3.png" alt="" />
<div class="mask"></div>
<div class="big">
<img src="img/big.jpg" alt="" class="bigImg" />
</div>
</div>
</div>
<script>
// 获取元素
var preview = document.querySelector(".preview");
var mask = document.querySelector(".mask");
var big = document.querySelector(".big");
var bidImg = document.querySelector(".bigImg");
// 鼠标移入展示遮罩层和大图
preview.addEventListener("mouseover", function (e) {
mask.style.display = "block";
big.style.display = "block";
});
// 鼠标移出隐藏遮罩层和大图
preview.addEventListener("mouseout", function (e) {
mask.style.display = "none";
big.style.display = "none";
});
preview.addEventListener("mousemove", function (e) {
// 鼠标在盒子内的坐标
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
// 遮罩层的移动距离,减去mask的一半宽高是为了让鼠标位于mask中间
var maskX = x - mask.offsetWidth / 2;
var maskY = y - mask.offsetHeight / 2;
// 遮罩层最大移动距离
var maskMax = preview.offsetHeight - mask.offsetHeight;
// 遮罩层最大移动距离,不能超过父盒子
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 = big.offsetWidth - bidImg.offsetWidth;
// 大图的移动距离 = 大图最大移动距离 * 遮罩层移动距离 / 遮罩层最大移动距离
var bigX = (maskX * bigMax) / maskMax;
var bigY = (maskY * bigMax) / maskMax;
bidImg.style.left = bigX + "px";
bidImg.style.top = bigY + "px";
});
</script>
</body>
</html>
五、图片
- 小图
- 大图