本文介绍如何使用JavaScript实现一个支持动态加载图片的放大镜功能。通过HTML布局定义缩略图与预览区,利用CSS控制蒙层样式与定位,并结合onmouseenter、onmousemove等事件监听鼠标行为。代码实现了小图缩放、大图动态加载及蒙层跟随移动,适用于电商等需要节省流量且展示高清细节的场景。
在许多电商网站及图片展示平台中,商品图片通常具备放大查看的功能。
若希望图片能展示更多清晰细节,实现此类放大镜功能极具性价比:它既能通过小图满足大多数用户的浏览需求,又能通过放大机制展示更高清的内容。这既节省了不必要的大图流量消耗,又满足了用户对图片清晰度的要求。
本文将利用前端技术实现一个简易的图片放大镜功能,旨在为开发者提供参考。
图片放大镜效果
首先观察图片放大镜的最终视觉效果。

如图所示,
左侧小图区域内包含待放大的图片,其上覆盖一个蒙层区域(即放大镜效果),该蒙层仅能在小图范围内移动,蒙层所覆盖的区域对应需要放大的部分。
右侧大图区域展示的是蒙层部分放大后的清晰图像,其本质是显示完整像素的图片,或者是比左侧小图像素更高的高清图片。
左侧蒙层的实时移动与右侧清晰图像的同步显示,共同构成了图片放大镜的功能效果。
接下来,我们将详细探讨其实现过程。
实现过程
一、设计UI界面
实现放大镜功能需先设计界面布局。从效果图可见,界面分为两部分:原始缩略小图区域和放大后的预览大图区域。在HTML中使用div进行布局,代码如下:
<div id="el_EnlargeContainer" class="enlarge">
<!--左边原始小图区域-->
<div id="el_SmallContainer" class="small">
<img id="el_SmallImage"/>
<div id="el_maskEnarge" class="mask"></div>
</div>
<!--右边预览大图区域-->
<div id="el_PreviewContainer" class="preview">
<img id="el_PreviewImage"/>
</div>
</div>从上述HTML代码可知,
外层定义了 el_EnlargeContainer 作为整个放大功能的内容区域,内部包含两个子元素:一个是缩略小图的div,内含img元素用于展示缩略图,以及一个蒙层的div元素;另一个是预览大图区域,包含放大后的大图img元素,此处加载的是原始大尺寸图片。
主要样式设置
蒙层需覆盖在缩略小图之上,因此需使用绝对定位,并设置带透明度的颜色,鼠标样式设置为 move,默认隐藏。具体CSS样式如下:
.mask {
position: absolute;
top: 0;
left: 0;
background: rgba(255, 255, 0, 0.6);
cursor: move;
display: none;
}预览大图区域样式类 preview,由于需显示在右侧区域,也可采用绝对定位方式,使其超出小图区域显示在右侧即可:
.preview {
position: absolute;
top: 0;
left: 150px;
/* ... */
}其他样式设置较为简单,根据布局方式逐一展示即可,此处略过。
接下来,我们需要处理图片加载逻辑。
二、加载缩略小图
上述代码中仅定义了img标签元素,并未直接加载图片资源,这是因为我们要通过动态加载图片的方式来实现放大镜功能。
当动态加载图片资源后,需根据图片像素宽高,设置对应界面元素的大小和位置信息。
缩略小图作为首要展示资源,需先加载并设置小图区域容器和图片的大小:
el_SmallImage.onload = () => {
let { width, height } = el_SmallImage
const smallScale = Math.min(SMALLSIZE / width, SMALLSIZE / height, 1)
smallImgWidth = width * smallScale
smallImgHeight = height * smallScale
el_EnlargeContainer.style.width = el_SmallImage.style.width = smallImgWidth + 'px'
el_EnlargeContainer.style.height = el_SmallImage.style.height = smallImgHeight + 'px'
resolve(el_SmallImage)
}
el_SmallImage.src = imgSrc上述代码在加载缩略小图后,获取图片的宽高数据并进行相应计算。其中 SMALLSIZE 是预先定义的常量,表示小图区域的固定尺寸大小,可根据需要自定义取值。通过该值计算缩略图的缩放比例,使缩略图依据该固定尺寸,计算合适的宽高比例进行展示。
注意,此处设置的是整个放大镜的整体内容区域 el_EnlargeContainer 的大小,即小图展示的大小,而预览放大的图片是浮在右侧的,并不包含在该区域内。
此时的缩略图即为我们网站稳定展示的图片信息,作为用户初始浏览的内容,效果如下:

一般电商网站上,常使用轮播图切换的方式展示缩略图片信息。
从上图可见,仅展示了缩略图片,放大后的预览大图尚未涉及,这是因为我们可以在监听事件中加载,有利于节省图片加载流量。
三、缩略图事件监听
接下来,我们需要处理缩略小图的事件监听,以实现加载预览大图和蒙层移动的效果。
根据上述HTML布局,我们在缩略小图的外部容器 el_SmallContainer 上添加鼠标事件,主要是 onmouseenter、onmouseleave、onmousemove 三个事件。
onmouseenter 事件,当鼠标进入页面展示的缩略图时进行处理,此时需做两件事:一是加载预览大图的原始图像,二是显示蒙层和预览大图的完整内容区域。
el_SmallContainer.onmouseenter = async () => {
// 加载预览大图原始图
if (loadPreviewImage === null) {
loadPreviewImage = await setPreviewImage(previewImgUrl)
}
// 显示蒙层和预览大图区域
el_maskEnarge.style.display = 'block'
el_PreviewContainer.style.display = 'block'
}上述代码即为鼠标进入事件的处理,其中包含加载并设置预览大图的原始数据信息,具体代码如下:
let { width, height } = el_PreviewImage
let previewScale = Math.min(PREVIEWSIZE / width, PREVIEWSIZE / height, 1)
el_PreviewContainer.style.width = width * previewScale + 'px'
el_PreviewContainer.style.height = height * previewScale + 'px'
el_PreviewContainer.style.left = (smallImgWidth + 10) + 'px'
el_maskEnarge.style.width = smallImgWidth * previewScale + 'px'
el_maskEnarge.style.height = smallImgHeight * previewScale + 'px'上述代码用于加载预览大图,此时能获取到图片的原始宽高数据,其中 PREVIEWSIZE 也是预先定义的常量,表示预览大图区域的固定尺寸大小。大图宽高与PREVIEWSIZE尺寸计算出对应的缩放比,用于计算实际展示区域的尺寸。
而 el_PreviewContainer 预览大图容器内容需定位在右侧区域,设置 left 样式属性。
另外,蒙层的大小也需设置。蒙层大小是在缩略小图区域展示的,但要使用预览大图的缩放比,这样才能得到准确的蒙层内容,用于在右侧放大区域呈现放大效果。
onmouseleave 事件较为简单,当鼠标离开缩略图内容区域时,隐藏蒙层和预览大图区域,放大镜效果随之隐藏:
el_SmallContainer.onmouseleave = () => {
el_maskEnarge.style.display = 'none'
el_PreviewContainer.style.display = 'none'
}定义了放大镜的显示和隐藏事件后,需处理移动效果,移动实现实时放大,使用到 onmousemove 鼠标事件。
四、实现放大
鼠标移动也是在缩略小图内容区域,对 el_SmallContainer 元素进行事件监听:
el_SmallContainer.onmousemove = (event) => {
// ...
}在该事件中,我们需要处理以下几件事:
获取鼠标移动的位置信息
let x = event.pageX - el_EnlargeContainer.offsetLeft - el_maskEnarge.offsetWidth / 2
let y = event.pageY - el_EnlargeContainer.offsetTop - el_maskEnarge.offsetHeight / 2上述代码中读取了蒙层的offset数据,是为了在移动时,让鼠标显示在蒙层的中心位置。
限制蒙层移动的范围,不能超出缩略小图内容区域
const xMax = el_SmallContainer.offsetWidth - el_maskEnarge.offsetWidth
x = x < 0 ? 0 : (x > xMax ? xMax : x)
const yMax = el_SmallContainer.offsetHeight - el_maskEnarge.offsetHeight
y = y < 0 ? 0 : (y > yMax ? yMax : y)更新蒙层的位置信息,实时移动蒙层元素
el_maskEnarge.style.left = x + 'px'
el_maskEnarge.style.top = y + 'px'设置预览大图显示的位置信息
const rate = el_PreviewImage.offsetWidth / el_SmallContainer.offsetWidth
el_PreviewImage.style.marginTop = -(rate * y) + 'px'
el_PreviewImage.style.marginLeft = -(rate * x) + 'px'上述代码是在一定的内容区域里加载一张完整原始尺寸的大图,但多余部分先隐藏 overflow: hidden;。然后计算缩略小图和预览大图的比值,右侧的预览大图等比例移动,通过使用 marginTop 和 marginLeft 属性设置定位的方式来移动。注意,此处处理的是 el_PreviewImage 原始大图元素。数据取负值,是相对于初始加载时左上角的值。
总结
至此,一个支持非固定尺寸、动态加载图片的放大镜功能基本完成。
动态加载图片无需考虑图片的像素宽高,任意尺寸的图片均可完整放大,缩略小图和预览大图也可以是同一张图片。
此外,放大镜的内容显示区域是根据不同图片的比例进行动态计算的,尺寸大小可变,但能通过常量设定控制在一定范围内。
图片放大镜功能的大部分代码已在文章中列出,根据这些内容,还可适当修改,更改成各种符合需求的插件。
固定尺寸
许多网站在处理放大镜功能时,采用固定尺寸缩略小图和预览大图的方式。
我们同样可以处理固定尺寸,此时需要特定尺寸的缩略小图和原始大图,直接设置元素的固定尺寸,缩略图也可直接加载:
/* 放大镜区域的大小 */
.enlarge {
/* ... */
width: 150px;
height: 150px;
}
/* 缩略小图的大小 */
.small img {
width: 150px;
height: 150px;
}
/* 蒙层大小 */
.mask {
/* ... */
width: 75px;
height: 75px;
}
/* 预览大图区域的大小 */
.preview {
/* ... */
width: 300px;
height: 300px;
}<img id="el_SmallImage" src="chrome.png"/>上述代码通过CSS直接设置各区域的宽高大小,缩略图也是直接加载,如此处理便无需手动设定各元素的宽高。
同样可在鼠标进入事件中加载原始大图,此时图片尺寸也是固定的。
其他事件处理基本相同,这样即可增加一个固定图像尺寸和固定界面尺寸的放大镜功能。
到此这篇关于基于JavaScript实现图片放大镜功能的文章就介绍到这了,更多相关JavaScript图片放大镜内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!