基于JavaScript实现动态加载图片的放大镜功能

作者:拾光

时间:2026-10-30

浏览:602

本文介绍如何使用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图片放大镜内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章