电商详情页的经典三件套:缩略图列表 + 中等图展示 + 局部放大图。本文js原生代码实现一条无依赖、可复用、可扩展的放大镜链路,涵盖事件委托、边界计算、背景定位三大核心技能。
效果预览

一、HTML 骨架
html
<div class="container">
<!-- 中等图 -->
<div class="left-img">
<div class="mask"></div>
</div>
<!-- 放大图 -->
<div class="right-img"></div>
<!-- 缩略图列表 -->
<ul class="img-list"></ul>
</div>
left-img
:中等图,承担点击切换与鼠标探测双重职责mask
:绝对定位遮罩,用于局部高亮与边界计算right-img
:放大图,背景图定位实现局部放大效果
二、数据约定
js
var imgs = {
small: ['imgA_1.jpg', 'imgB_1.jpg', 'imgC_1.jpg'],
middle: ['imgA_2.jpg', 'imgB_2.jpg', 'imgC_2.jpg'],
large: ['imgA_3.jpg', 'imgB_3.jpg', 'imgC_3.jpg']
}
- 三张图按索引一一对应,切换时只需同步
backgroundImage
- 缩略图定宽定高,中等图与放大图定宽不定高,保持比例
三、JS链式事件三步走
1.初始化:渲染缩略图 + 默认激活
js
function initPage() {
let html = ''
for (let i = 0; i < imgs.small.length; i++) {
html += `<li style="background-image:url(./images/${imgs.small[i]});"></li>`
}
$('.img-list').innerHTML = html
$('.img-list li').style.border = '2px solid #000' // 默认选中第一张
}
2.点击缩略图:同步切换中等图与大图
js
$('.img-list').onclick = function (e) {
if (e.target.tagName !== 'LI') return
// 让所有 LI 失活
$$('li').forEach(li => li.style.border = 'none')
// 让当前 LI 激活
e.target.style.border = '2px solid #000'
const index = [].indexOf.call(this.children, e.target)
$('.left-img').style.backgroundImage = `url(./images/${imgs.middle[index]})`
$('.right-img').style.backgroundImage = `url(./images/${imgs.large[index]})`
}
使用事件委托,缩略图数量随意增减,无需重新绑定。
3.鼠标移动:遮罩层跟随 + 大图定位
js
$('.left-img').onmousemove = function (e) {
const mask = $('.mask')
const large = $('.right-img')
mask.style.opacity = 1
large.style.opacity = 1
// 计算遮罩层中心坐标
let left = e.clientX - this.offsetLeft - mask.offsetWidth / 2
let top = e.clientY - this.offsetTop - mask.offsetHeight / 2
// 边界条件:不让遮罩跑出中等图
left = Math.max(0, Math.min(left, this.offsetWidth - mask.offsetWidth))
top = Math.max(0, Math.min(top, this.offsetHeight - mask.offsetHeight))
mask.style.left = left + 'px'
mask.style.top = top + 'px'
// 大图反向移动,实现局部放大
large.style.backgroundPositionX = -left + 'px'
large.style.backgroundPositionY = -top + 'px'
}
边界计算拆解
left ≤ 0
时强制归零left ≥ (中等图宽 - 遮罩宽)
时强制贴边- 同理处理
top
高度方向
背景定位技巧
遮罩向右移动 10px,大图背景向左移动 10px,形成「窗口」效果;Y 轴同理。
四、鼠标离开:自动隐藏
js
$('.left-img').onmouseleave = function () {
$('.mask').style.opacity = 0
$('.right-img').style.opacity = 0
}
只用
opacity
控制显隐,避免display: none
触发重排;背景图已预加载,无闪烁。
性能 & 扩展
- 零依赖:原生 DOM API,gzip < 1 KB
- 零重排:仅用
opacity
与background-position
,不改动布局 - 可异步:把
initPage
换成fetch
即可接入后端图片列表 - 可响应:把
offsetWidth
换成getBoundingClientRect
即可适配缩放