持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情
highlight: a11y-dark
整体代码在最下方
放大镜特效如图(这种效果一般只有pc端的商品详情展示能用到 )
做法:
主要通过外层div的onmousemove事件获取X,Y坐标,同时设置蒙版的位置,做到蒙版跟随鼠标移动,再将右侧大图的位置根据一定的比例缩放移动,显示对应位置的图片。
HTML
通过监听.preview-box的onmousemove,给里面的.mask元素设置位置,当执行onmousemove时,让.mask元素显现,.mask默认隐藏,用visibility: hidden;让其隐藏,因为后面会用到.mask元素的宽高,所以不能使用display:none让其隐藏,然后禁止.mask的鼠标事件因为会跟外层的onmousemove冲突,需要给.mask设置 pointer-events: none;移除其鼠标事件。
<body>
<div class="container">
<div class="preview-box">
<img src="img/img.png" alt="">
<div class="mask"></div>
</div>
<div class="big-box">
<img class="big-img" src="img/img.png" alt="">
</div>
</div>
</body>
.mask样式如图
当鼠标放上去之后显示蒙版跟右侧大图
.preview-box .mask {
position: absolute;
top: 0;
left: 0;
width: 120px;
height: 120px;
background-color: aqua;
opacity: 0.5;
/* 使用 display: none; 在 js 中无法获取元素的宽高 */
visibility: hidden;
/* 取消蒙板的鼠标事件 */
pointer-events: none;
}
.preview-box:hover .mask {
visibility: visible;
}
.preview-box:hover+.big-box {
visibility: visible;
}
JS
获取外层.preview-box跟.mask元素
然后获取预览区域的内容大小,蒙板大小
获取放大显示区的大小,计算放大的倍数,设置大图的大小
根据 move 事件获取鼠标位置,动态设置蒙板位置
将鼠标的坐标位置转换为蒙板定位的位置,将鼠标控制在蒙板的中心,将鼠标位置的边缘进行处理
最终将处理过的值最终设置为样式,根据蒙板的位置确定大图的位置
获取预览区域的内容大小
var previewBox = document.querySelector('.preview-box');
var mask = document.querySelector('.mask');
var previewWidth = previewBox.clientWidth;
var previewHeight = previewBox.clientHeight;
var bigBox = document.querySelector('.big-box');
var bigImg = document.querySelector('.big-img');
获取蒙板大小
var maskWidth = mask.offsetWidth;
var maskHeight = mask.offsetHeight;
获取放大显示区的大小
var bigWidth = bigBox.clientWidth;
var bigHeight = bigBox.clientHeight;
计算放大的倍数
var scale = bigWidth / maskWidth;
设置大图的大小
bigImg.style.width = previewWidth * scale + 'px';
bigImg.style.height = previewHeight * scale + 'px';
根据 move 事件获取鼠标位置
previewBox.onmousemove = function (e) {
// 鼠标位置
var mouseX = e.offsetX;
var mouseY = e.offsetY;
}
动态设置蒙板位置,将鼠标的坐标位置转换为 蒙板定位的位置
将鼠标控制在蒙板的中心
var maskLeft = mouseX - maskWidth / 2;
var maskTop = mouseY - maskHeight / 2;
将蒙版位置进行边缘处理
maskLeft = maskLeft < 0 ? 0 : maskLeft;
maskLeft = maskLeft > (previewWidth - maskWidth) ? (previewWidth - maskWidth) : maskLeft;
maskTop = maskTop < 0 ? 0 : maskTop;
maskTop = maskTop > (previewHeight - maskHeight) ? (previewHeight - maskHeight) : maskTop;
将处理过的值最终设置为样式
mask.style.left = maskLeft + 'px';
mask.style.top = maskTop + 'px';
根据蒙板的位置确定大图的位置
bigImg.style.left = -maskLeft * scale + 'px';
bigImg.style.top = -maskTop * scale + '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>
.container {
position: relative;
width: 300px;
height: 300px;
border: 2px solid #666;
}
.preview-box {
position: relative;
width: 100%;
height: 100%;
}
.preview-box img {
display: block;
width: 100%;
height: 100%;
pointer-events: none;
}
.preview-box .mask {
position: absolute;
top: 0;
left: 0;
width: 120px;
height: 120px;
background-color: aqua;
opacity: 0.5;
/* 使用 display: none; 在 js 中无法获取元素的宽高 */
visibility: hidden;
/* 取消蒙板的鼠标事件 */
pointer-events: none;
}
.preview-box:hover .mask {
visibility: visible;
}
.preview-box:hover+.big-box {
visibility: visible;
}
.big-box {
visibility: hidden;
position: absolute;
top: -2px;
left: 300px;
width: 500px;
height: 500px;
border: 2px solid #666;
overflow: hidden;
}
.big-box .big-img {
position: absolute;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div class="container">
<div class="preview-box">
<img src="img/img.png" alt="">
<div class="mask"></div>
</div>
<div class="big-box">
<img class="big-img" src="img/img.png" alt="">
</div>
</div>
</body>
<script>
var previewBox = document.querySelector('.preview-box');
var mask = document.querySelector('.mask');
// 获取预览区域的内容大小
var previewWidth = previewBox.clientWidth;
var previewHeight = previewBox.clientHeight;
var bigBox = document.querySelector('.big-box');
var bigImg = document.querySelector('.big-img');
// 获取蒙板大小
var maskWidth = mask.offsetWidth;
var maskHeight = mask.offsetHeight;
// 获取放大显示区的大小
var bigWidth = bigBox.clientWidth;
var bigHeight = bigBox.clientHeight;
// 计算放大的倍数
var scale = bigWidth / maskWidth;
// 设置大图的大小
bigImg.style.width = previewWidth * scale + 'px';
bigImg.style.height = previewHeight * scale + 'px';
// 根据 move 事件获取鼠标位置
previewBox.onmousemove = function (e) {
// 鼠标位置
var mouseX = e.offsetX;
var mouseY = e.offsetY;
// 动态设置蒙板位置,将鼠标的坐标位置转换为 蒙板定位的位置
// 将鼠标控制在蒙板的中心
var maskLeft = mouseX - maskWidth / 2;
var maskTop = mouseY - maskHeight / 2;
// // 边缘处理
maskLeft = maskLeft < 0 ? 0 : maskLeft;
maskLeft = maskLeft > (previewWidth - maskWidth) ? (previewWidth - maskWidth) : maskLeft;
maskTop = maskTop < 0 ? 0 : maskTop;
maskTop = maskTop > (previewHeight - maskHeight) ? (previewHeight - maskHeight) : maskTop;
// 将处理过的值最终设置为样式
mask.style.left = maskLeft + 'px';
mask.style.top = maskTop + 'px';
// 根据蒙板的位置确定大图的位置
bigImg.style.left = -maskLeft * scale + 'px';
bigImg.style.top = -maskTop * scale + 'px';
}
</script>
</html>