本文详细解析如何使用HTML、CSS和JavaScript实现图片放大镜效果。重点讲解鼠标移入移出时的显示控制、mousemove事件中相对坐标的计算原理,特别是absolute定位与transform对offsetLeft/Top的影响。通过数学比例计算实现大图跟随鼠标移动,并限制查看范围,提供完整代码参考。
效果演示
本文分享使用HTML、CSS和JavaScript实现图片放大镜功能的具体代码,供读者参考学习。
效果演示

JS 详解
JS 详解
HTML结构和CSS样式代码已置于文章末尾的源代码部分,此处仅对JavaScript核心逻辑进行详细解析。
获取操作对象
首先,需要获取需要操作的目标元素:
- 图片展示框(用于监听鼠标移入事件)
- 放大镜容器(控制其显示状态及跟随鼠标移动)
- 放大镜内部图片(根据计算结果改变位置)
let imgShow = document.querySelector('.img-show'); // 图片展示框
let imgLarge = document.querySelector('.img-large'); // 放大镜
let img = document.querySelector('img'); // 放大镜中图片鼠标移入事件处理
为图片展示框添加事件监听器,当鼠标移入该区域时,使放大镜显示:
imgShow.addEventListener('mouseover', function() {
// 鼠标移入图片时,显示放大镜
imgLarge.style.display = "block";
});鼠标移动事件监听
监听鼠标在图片展示框内移动的事件:
imgShow.addEventListener('mousemove', function(event) {
// 计算鼠标在图片展示框中相对位置
let x = event.pageX - this.offsetLeft;
let y = event.pageY - this.offsetTop;
});注意:打印输出的x和y值显示,鼠标相对于图片展示框的位置可能出现负数,如下图所示:

理论上这些值应为正数。这是因为图片展示框使用了absolute定位,并通过transform进行了二次平移以实现水平垂直居中。暂时注释掉transform的平移效果后再次打印x和y值:

此时相对位置均变为正值。这表明transform的平移操作不影响offsetLeft和offsetTop的值。对于absolute定位,offsetLeft和offsetTop仍使用原始位置的值,坐标系也未改变,依然以原始位置的左上角为基准。这就是出现负值的原因,可通过一张动图来理解鼠标相对位置的参考坐标系:

理解了x和y值的含义后,即可进行下一步的数学计算。
放大镜跟随鼠标移动实现
接下来实现放大镜跟随鼠标移动的功能:
// 放大镜跟随鼠标移动
imgLarge.style.left = (x + 480 - 125)+'px';
imgLarge.style.top = (y + 270 - 125)+'px';基于上述坐标系,(x + 480)用于让放大镜始终跟随鼠标,(- 125)用于让鼠标指针始终保持在放大镜的中心位置(因为放大镜宽度为250px)。若不理解,可先移除+480和-125查看效果,再逐个添加观察变化。此处不再演示。
限制查看范围
限制放大镜的查看范围:
// 放大镜超出范围后消失
if (x < -480 || x > 480 || y < -270 || y > 270) {
imgLarge.style.display = "none";
}内部图片移动计算
放大镜中图片的移动:
// 放大镜中图片位置的移动
img.style.left = (-(x+480)*2 + 125)+'px';
img.style.top = (-(y+270)*2 + 125)+'px';原理是计算两张图片之间的比例,根据鼠标在图片展示框中的相对位置,计算出放大镜中图片的位置偏移量,从而实现图片的移动。
- (x+480)用于回归原始位置坐标系
- *2表示两张图片的比例
- -(x+480)*2添加负号是为了实现同方向移动,否则移动方向相反,可自行尝试验证。
- +125如果不添加,会发现放大位置与原始位置不对齐,可自行尝试验证。
源代码
源代码
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>放大镜效果</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background: url(./images/bg.jpg);
background-size: cover;
}
/* 背景图片高斯模糊 */
body::before {
content: "";
position: absolute; /* 一定要用绝对定位 */
width: 100%;
height: 100%;
backdrop-filter: blur(30px); /* 模糊半径 */
}
.img-show {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 960px;
height: 540px;
border: 2px solid #bebebe;
border-radius: 15px;
box-shadow: 8px 8px 20px rgba(0, 0, 0, .3), -8px -8px 20px rgba(0, 0, 0, .3);
background: url(./images/show.jpg);
background-size: cover;
}
.img-show .img-large {
display: none;
position: absolute;
width: 250px;
height: 250px;
border: 2px solid #bebebe;
border-radius: 125px;
overflow: hidden;
background-color: #fff;
}
/* 放大镜中间的准心 */
.img-show .img-large::after {
content: "+";
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
color: #3e3e3e;
font-size: 30px;
}
/* 放大镜显示时隐藏鼠标指针 */
.img-show .img-large:hover {
cursor: none;
}
.img-show .img-large img {
position: absolute;
width: 1920px;
border-radius: 15px;
}
</style>
</head>
<body>
<div class="img-show">
<div class="img-large">
<img src="./images/show.jpg" alt="">
</div>
</div>
<script>
// 获取需要操作的对象
let imgShow = document.querySelector('.img-show');
let imgLarge = document.querySelector('.img-large');
let img = document.querySelector('img');
// 鼠标移入图片时,显示放大镜
imgShow.addEventListener('mouseover', function() {
imgLarge.style.display = "block";
});
// 放大镜跟随鼠标移动
imgShow.addEventListener('mousemove', function(event) {
// 计算鼠标在图片展示框中相对位置
let x = event.pageX - this.offsetLeft;
let y = event.pageY - this.offsetTop;
// 放大镜跟随鼠标移动
imgLarge.style.left = (x + 480 - 125)+'px';
imgLarge.style.top = (y + 270 - 125)+'px';
// 放大镜超出范围后消失
if (x < -480 || x > 480 || y < -270 || y > 270) {
imgLarge.style.display = "none";
}
// 放大镜中图片位置的移动
img.style.left = (-(x+480)*2 + 125)+'px';
img.style.top = (-(y+270)*2 + 125)+'px';
});
</script>
</body>
</html>以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。