放大镜的效果跟平常我们在电商网站中的商品详情页将商品放大查看的效果是一样的,效果图如下:
布局结构如下:
<div class="enlarge">
<div class="middleBox">
<img src="./img/1.jfif" alt="">
<div class="mask"></div>
<div class="bigBox">
<img src="./img/1.jfif" alt="">
</div>
</div>
<div class="smallBox">
<img src="./img/1.jfif" alt="">
<img src="./img/2.webp" alt="">
<img src="./img/3.webp" alt="">
</div>
</div>
css样式如下:
.middleBox{
width: 400px;
height: 400px;
position:relative;
}
.middleBox>img{
width: 400px;
height: 400px;
}
.middleBox .mask{
width: 100px;
height: 100px;
background-color: rgba(255,255,0,.7);
position:absolute;
left: 0;
top: 0;
display:none;
}
/*
布局的时候,有一个比例必须遵循:
中等盒子跟遮罩的大小比例 = 大图跟大盒子的大小比例
*/
.middleBox>.bigBox{
width: 300px;
height: 300px;
position:absolute;
left: 105%;
top: 0;
display:none;
overflow: hidden;
}
.middleBox>.bigBox>img{
width: 1200px;
height: 1200px;
position:absolute;
left: 0;
top: 0;
}
.smallBox img{
width: 80px;
height: 80px;
border:2px solid #000;
margin:20px 20px 0 0;
}
.smallBox img:first-child{
border-color:red;
}
.mask:hover{
cursor: move;
}
效果分为3个部分,第1部分是点击小图,换中等图和大图:
// 获取所有标签
var enlarge = document.querySelector('.enlarge');
var middleBox = enlarge.querySelector('.middleBox')
var bigBox = enlarge.querySelector('.bigBox')
var middleImg = enlarge.querySelector('.middleBox>img')
var bigImg = enlarge.querySelector('.bigBox>img')
var smallImgs = enlarge.querySelectorAll('.smallBox>img')
var mask = enlarge.querySelector('.mask')
// 点击小图换中图和大图
// 遍历所有小图
for(var i=0;i<smallImgs.length;i++){
// 给所有小图绑定单击事件
smallImgs[i].onclick = function(){
// 将所有小图的边框颜色改成黑色
for(var j=0;j<smallImgs.length;j++){
smallImgs[j].style.borderColor = '#000';
}
// 将当前点击的这个小图边框颜色改成红色
this.style.borderColor = 'red';
// 获取到当前点击的小图的路径
var src = this.getAttribute('src')
// 将小图的路径放到中图和大图中
middleImg.setAttribute('src',src)
bigImg.setAttribute('src',src)
}
}
第2部分是鼠标移入中等盒子让遮罩和大盒子显示,移出隐藏:
// 鼠标移入中盒子
middleBox.onmouseover = function(){
// 让遮罩和大盒子显示
mask.style.display = 'block';
bigBox.style.display = 'block';
}
// 鼠标移出中盒子
middleBox.onmouseout = function(){
// 让遮罩和大盒子隐藏
mask.style.display = 'none';
bigBox.style.display = 'none';
}
第3部分,鼠标在移入中等盒子后,让遮罩跟随鼠标移动,让大图跟随遮罩移动:
// 鼠标移入中盒子
middleBox.onmouseover = function(){
// 让遮罩和大盒子显示
mask.style.display = 'block';
bigBox.style.display = 'block';
// 鼠标在中盒子中移动
middleBox.onmousemove = function(){
// 获取鼠标当前在浏览器中的位置
var e = window.event;
var x = e.pageX;
var y = e.pageY;
// 根据光标位置计算遮罩的left和top = 光标位置 - 遮罩大小的一般 - 大盒子左边的间距
var l = x - mask.offsetWidth/2 - enlarge.offsetLeft;
var t = y - mask.offsetHeight/2 - enlarge.offsetTop;
// 限制left和top
if(l<0) l=0
if(t<0) t=0
if(l>middleBox.clientWidth-mask.offsetWidth) l=middleBox.clientWidth-mask.offsetWidth
if(t>middleBox.clientHeight-mask.offsetHeight){
t=middleBox.clientHeight-mask.offsetHeight
}
// 设置left和top
mask.style.left = l + 'px'
mask.style.top = t + 'px'
// 移动过程中计算大图需要移动的距离 = 遮罩在中盒子中移动的比例 * 大图的尺寸
// 计算遮罩在中盒子中移动的比例
var percentX = l / middleBox.clientWidth;
var percentY = t / middleBox.clientHeight;
// 根据比例计算大图需要移动的距离
var bigLeft = percentX * bigImg.offsetWidth
var bigTop = percentY * bigImg.offsetHeight
// 将计算好的大图需要移动的距离的设置给大图
bigImg.style.left = -bigLeft + 'px'
bigImg.style.top = -bigTop + 'px'
}
}