JavaScript基础 - 经典案例4 -放大镜 (含公式)

JS实现放大镜效果 首先放大镜的原理是通过移动前面小图片里面的小黑块的位置,然后移动后面大图片的位置。 那么可以先把要实现的效果列个步骤出来。 1.鼠标放到小盒子上面的小方格大图片框出来 2. 鼠标移出小盒子上面的小方格 大图片框消失 3.小方格随着鼠标移动 4.移动小方格大图片盒子的大图片随着移动 首先完成html还有css部分(偷了个懒,直接让大盒子和小方格的比例与大图片和小图片的比例一致,这样在后面计算大图片移动位... 阅读详情

用原生JS实现一个简易的放大镜功能

附带放大镜相关公式 以及 offsetX,offsetY抖动解决办法

效果如图:
在这里插入图片描述

先完成HTML结构:

<div class="zoom">
	<!-- 小图 -->
    <div class="smallImg">
    	<!-- 遮罩层 -->
        <div class="mask"></div>
    </div>
    <!-- 放置大图的div -->
    <div class="big">
    	<!-- 大图 -->
        <img class="bigImg" src="./image.jpg" alt="">
    </div>
</div>

CSS样式:

* {
    margin: 0;
    padding: 0;
}

.smallImg {
    position: absolute;
    width: 200px;
    height: 200px;
    left: 300px;
    top: 100px;
    border: 1px solid #ccc;
    background-image: url('./image.jpg');
    background-size: cover;
}

.mask {
    display: none;
    position: absolute;
    width: 50px;
    height: 50px;
    background-color: red;
    opacity: .3;
}

.big {
    /* 大图默认隐藏 */
    display: none;
    position: absolute;
    top: 100px;
    left: 502px;
    width: 300px;
    height: 300px;
    border: 1px solid #ccc;
    /* 让大图溢出部分隐藏 */
    overflow: hidden;
}

.bigImg {
    position: absolute;
    width: 1200px;
    height: 1200px;
}

实现放大镜的关键点

  • 鼠标移入小图区域时,显示大图和小图上的遮罩层,鼠标移出时,隐藏大图和遮罩层

获取元素,监听 mouseenter 鼠标进入和 mouseleave 鼠标离开事件,设置 display 的值即可

const smallImg = document.querySelector('.smallImg')
const mask = document.querySelector('.mask')
const big = document.querySelector('.big')
const bigImg = document.querySelector('.bigImg')

smallImg.addEventListener('mouseenter', () => {
    mask.style.display = 'block'
    big.style.display = 'block'
})

smallImg.addEventListener('mouseleave', () => {
    mask.style.display = 'none'
    big.style.display = 'none'
})
  • 监测到鼠标移动距离,控制遮罩层移动

首先要监听 mousemove 事件:mousemove 事件是一个实时响应的事件,当鼠标指针的位置发生变化时(至少移动一个像素),就会触发该事件

在事件回调中:可以通过形参 e 来接收鼠标事件对象,对象中有2个属性:
offsetX:当鼠标事件发生时,鼠标坐标 到 事件源元素左侧的距离
offsetY:当鼠标事件发生时,鼠标坐标 到 事件源元素顶部的距离

由于遮罩层开启了绝对定位,其父元素小图开启了相对定位,所以遮罩层的 left 和 top 是相对于小图的,可以通过设置 left 和 top 的值指定它在小图上的位置:

遮罩层的 left = e.offsetX - 遮罩层 offsetWidth / 2

遮罩层的 top = e.offsetY - 遮罩层 offsetHeight / 2

对于 offsetWidth、offsetHeight :

offsetWidth :元素的自身宽度,包含元素自身设置的 width + padding + border

offsetHeight :元素的自身高度,包含元素自身设置的 height + padding + border

smallImg.addEventListener('mousemove', (e) => {
	// 遮罩层移动距离
	let left = e.offsetX - mask.offsetWidth / 2
	let top = e.offsetY - mask.offsetHeight / 2
	
	mask.style.left = left + 'px'
	mask.style.top = top + 'px'
}

这样,遮罩层就可以跟随鼠标移动了

  • 限制遮罩层移动范围

但我们会发现一个bug:遮罩层可能会移出小图区域,像这样:

在这里插入图片描述
因为我们只想要放大小图,所以遮罩层的活动范围应该完全限制在小图的宽高里面
遮罩层的 left 的最小值 = 0
遮罩层的 left 的最大值 = 小图的 offsetWidth - 遮罩层的 offsetWidth - 2

此处为什么要减 2 ?
因为小图两边有 2px 的 border,offsetWidth 是包含border的,而 left 的最大值应该是小图的 width - 遮罩层的 width,应该减去 border 的宽度

同理:
遮罩层的 top 的最小值 = 0
遮罩层的 top 的最大值 = 小图的 offsetHeight - 遮罩层的 offsetHeight - 2

// 控制遮罩层移动范围
left < 0 ? left = 0 : left
left > smallImg.offsetWidth - mask.offsetWidth - 2 ? left = smallImg.offsetWidth - mask.offsetWidth - 2 : left

top < 0 ? top = 0 : top
top > smallImg.offsetHeight - mask.offsetHeight - 2 ? top = smallImg.offsetHeight - mask.offsetHeight - 2 : top
  • 设置大图的移动方向和距离

将放置大图div的样式 overflow: hidden; 去掉,我们可以观察到:遮罩层的 left 值变化和大图的 left 值变化方向是相反的,top 值同理

在这里插入图片描述

而移动距离,与放大镜倍数有关:

大图移动距离 = - 遮挡层移动距离 left × 放大镜倍数

放大镜倍数 = 大图宽高 / 小图宽高

示例的放大镜倍数 = 1200px / 200px = 6

// 大图移动距离
bigImg.style.left = -left * 6 + 'px'
bigImg.style.top = -top * 6 + 'px'

需要注意的一点是,我们应当保证:大图宽高 / 放置大图的div宽高 = 小图宽高 / 小图遮罩层宽高,才能实现放大镜效果

在本例中:1200px / 300px = 200px / 50px

  • 关于 offsetX,offsetY 抖动的问题

练习过程中发现随着鼠标移动,遮罩层一直抖动,

在这里插入图片描述

我们虽然监听的是小图的 mousemove 事件,但小图和其子元素遮罩层都会触发该事件,当鼠标在遮罩层上时,mousemove 事件对象是遮罩层元素,当鼠标在小图上时,事件对象又变成了小图元素,offsetX是鼠标到触发事件对象的位置。所以当事件对象是遮罩层时offsetX的值比较小,计算后会移到左上角,但移动后事件对象又变成小图元素了,计算后又回到了鼠标位置,循环反复,造成了闪动效果。

解决方案:给遮罩层添加css属性:pointer-events: none;

让遮罩层不参与鼠标事件,event.target 一直是小图,就可以解决了

完整代码:

<!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>
        * {
            margin: 0;
            padding: 0;
        }

        .smallImg {
            position: absolute;
            width: 200px;
            height: 200px;
            left: 300px;
            top: 100px;
            border: 1px solid #ccc;
            background-image: url('./image.jpg');
            background-size: cover;
        }

        .mask {
            display: none;
            position: absolute;
            width: 50px;
            height: 50px;
            background-color: red;
            opacity: .3;
            pointer-events: none;
        }

        .big {
            /* 大图默认隐藏 */
            display: none;
            position: absolute;
            top: 100px;
            left: 502px;
            width: 300px;
            height: 300px;
            border: 1px solid #ccc;
            /* 让大图溢出部分隐藏 */
            overflow: hidden;
        }

        .bigImg {
            position: absolute;
            width: 1200px;
            height: 1200px;
        }
    </style>
</head>

<body>
    <div class="zoom">
        <div class="smallImg">
            <div class="mask"></div>
        </div>
        <div class="big">
            <img class="bigImg" src="./image.jpg" alt="">
        </div>
    </div>
    <script>
        const smallImg = document.querySelector('.smallImg')
        const mask = document.querySelector('.mask')
        const big = document.querySelector('.big')
        const bigImg = document.querySelector('.bigImg')

        smallImg.addEventListener('mouseenter', () => {
            mask.style.display = 'block'
            big.style.display = 'block'
        })

        smallImg.addEventListener('mouseleave', () => {
            mask.style.display = 'none'
            big.style.display = 'none'
        })

        smallImg.addEventListener('mousemove', (e) => {
            // 遮罩层移动距离
            let left = e.offsetX - mask.offsetWidth / 2
            let top = e.offsetY - mask.offsetHeight / 2
            // 控制遮罩层移动范围
            left < 0 ? left = 0 : left
            left > smallImg.offsetWidth - mask.offsetWidth - 2 ? left = smallImg.offsetWidth - mask.offsetWidth - 2 : left

            top < 0 ? top = 0 : top
            top > smallImg.offsetHeight - mask.offsetHeight - 2 ? top = smallImg.offsetHeight - mask.offsetHeight - 2 : top

            mask.style.left = left + 'px'
            mask.style.top = top + 'px'

            // 大图移动距离
            bigImg.style.left = -left * 6 + 'px'
            bigImg.style.top = -top * 6 + 'px'
        })
    </script>
</body>
</html>

结束;

使用JavaScript实现放大镜效果(有详细注释) 如何使用JavaScript实现放大镜效果 阅读详情

相关推荐

JS案例-仿京东放大镜效果

需要实现的效果图如下: ①布局:布局采用一个大盒子里面首先分为上下两个部分,然后下部分又分为左右两个部分。左边的盒子里面放了一个img和一个遮罩层cover,右边盒子里面放的是800*800的大图片,这里提供左边的图片b3.png和右边的大图片big.jpg: 注意:左边盒子里面的cover采用绝对定位,右边盒子里面的img采用绝对定位。 ②功能实现:主要有三个功能模块: 1.鼠标经过(mouseover)左边盒子,黄色的遮罩层以及右边盒子显示,鼠标离开(mouseout)则隐藏黄色遮罩层以

qq_43781887的博客 2127

js实现放大镜(详细注释)

大致步骤:首先我们应该先构思好布局:1:先有一个div存放原始图片。2:再有一个div存放放大后的图片。3:来一个遮罩层让用户道自己正在观察哪个区域,并且实现遮罩层跟随鼠标移动而移动。4:显示放大后的图片。hover的小知识点: hover后面一般都是控制子元素,无法控制父元素的效果 hover更改同级(兄弟)元素属性:更改兄弟元素又分两种情况:需要更改的兄弟元素是当前元素的相邻元素,也就是说紧接着当前元素,在hover后面使用‘+’号链接就行,就是.event1:hover + .big需要改变的兄

H-rosy的博客 2900

JavaScript 放大镜特效

效果展示 页面布局 资源下载 放大镜特效 目录布局 index.html 代码 &lt;!DOCTYPE html&gt; &lt;html lang="en"&gt; &lt;head&gt; &lt;meta charset="UTF-8"&gt; &lt;title&gt;放大镜特效&lt;/title&gt; &lt;style

Nancy 博客 844

js实现放大镜效果

思路: 先让mask块和bigImg块、big块隐藏,当鼠标经过pre_img就显示遮罩层mask和big块,获取鼠标当前的位置,根据“ 大图片移动距离 = 遮挡层移动距离*大图片最大移动距离 / 遮挡层最大移动距离 ”实现放大镜效果 大概思路实现图: html + css 代码: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></t...

qq_65325072的博客 6472

js实现简单放大镜效果

用js实现简单放大镜效果,供大家参考,具体内容如下 此处放大镜实现的效果就是当鼠标放置在图片上会有半透明遮罩,图片的一个区域就会被放大,然后展示在右边。当鼠标移动时右边的大图片也会局部移动。这里的放大并不是真正的放大,而是等比例移动。下面是实现的代码: css样式代码如下: <style> .s_box{width:400px;height: 300px;position: absolute;left: 50px;top:100px;} .s_box img{width: 400px;height: 300px;} .s_box span{width: 130px;height: 10

交换芯片数据通路四大核心微架构深度解析

数据通路是交换芯片性能的物理根基,决定着低延迟、高吞吐与突发承载能力。其本质是在硅片约束下对带宽、时序、功耗与统计复用的系统性权衡。Crossbar提供确定性低延迟但受RC延迟与功耗制约;VOQ通过虚拟队列隔离输出争抢,却引入仲裁复杂度与内存开销;Shared Buffer依托统计复用提升缓存利用率,但面临碎片化与管理策略挑战;Cell Fabric以固定长度cell重构交换粒度,在AI与金融等小包敏感场景实现尾延迟稳定。这些架构并非替代关系,而是面向不同网络不确定性(如流量不对称性、突发强度、包长分布)的

weixin_32667955的博客 189

从零开始学习 JavaScript APl(七):实例解析关于京东案例头部案例和放大镜效果!

欢迎来到JSAPL(JavaScript Algorithms and Data Structures Projects)学习项目!这个项目旨在为学习JavaScript算法和数据结构提供一个实践平台。通过完成这些项目,您将掌握常见的算法和数据结构,并学会如何用JavaScript实现它们。无论您是初学者还是有经验的开发人员,JSAPL将为您提供有趣和具有挑战性的练习,帮助您建立自己的算法和数据结构知识库。加入我们,享受学习的过程!提示:以下是本篇文章正文内容,下面案例可供参考。

阿猫故乡的博客 1489

ROS2初级面试题汇总

总结和收集了一些关于ros2的问题和解答记录

qq_57633442的博客 5565

js商品放大镜案例

js商品放大镜案例 效果图: 左边是商品图片,右边是放大效果 代码:记得把图片路径换成自己的 <style> .con{ padding: 200px 0 0 200px; } .box{ width: 300px; box-sizing: border-box; position: relative; }

weixin_41824429的博客 383

描述符链表(Descriptor Chain)是什么?

描述符链表是硬件加速数据传输的核心数据结构,通过链式描述符(包含地址、长度、控制标志等)实现DMA自动批量处理,显著降低CPU负载。其工作原理为:CPU初始化链表后,硬件按序处理每个描述符,完成自动跳转与中断通知。在网卡收包、NVMe存储等场景中应用广泛,优势包括批处理、低延迟和灵活调度。需注意内存对齐、缓存一致性等实现细节,优化手段包括预分配描述符池、环形缓冲区等。该技术是网络/存储领域提升吞吐量的关键方案。

guigenyi的专栏 775

XGBoost调参新姿势:Bayesian优化实战指南(附完整代码)

本文详细介绍了如何使用Bayesian优化方法高效调优XGBoost模型参数。通过解析Bayesian优化核心原理和XGBoost关键参数,提供完整的实战代码示例,帮助读者掌握这一智能调参技术,显著提升模型性能。文章特别适合机器学习工程师和数据科学家阅读。

weixin_42536058的博客 366

JavaScript 笔记-放大镜案例

思路 做什么 需要什么东西 实现什么功能 1.首先需要准备两个大小不一样的盒子,小盒子在左边,大盒子在右边,小盒子内有一个更小的盒子,以下称为小放(小放大镜),大盒子以下称为大放(大放大镜) 2.将需要放大的图片放入两个盒子中,图片的尺寸参考:大图/小图=大放/小放 3.用相对定位,将小放固定在小盒子的左上角 4.先将小放和大放隐藏,设置将鼠标移入小图时显示(添加鼠标移入事件),鼠标移除时隐藏(...

hover_的博客 235

SAP UI5 百科全书的目录

笔者 12 年 SAP UI5 开发岁月中写下的 595 篇 SAP UI5 学习笔记,全部收录到《SAP UI5 百科全书》专栏中去,目录如下。请大家按照自己的学习需要,根据关键字搜索到对应的文章,然后进行学习。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 3827

原生js实现图片放大镜效果

原生js实现图片放大镜效果 放大镜原理 -------------------------------------------------------------———————————————— 放大镜的实现过程是将一个小图放置在一个盒子里。宽高都是100%。当鼠标在小图盒子里移动时,出现一个移动块(阴影区域)。右侧大图片盒子出现一个等比例放大的在小图盒子移动块中的图片内容。如图(请勿过于认真看图...

weixin_43757541的博客 901

基于YOLOv8的植物生长阶段识别系统设计与实现

本文详细介绍了一个基于YOLOv8深度学习模型的植物生长阶段识别系统,包含完整的数据集构建、模型训练、评估以及基于PyQt5的用户界面开发过程。系统能够自动识别植物在不同生长阶段(如发芽期、生长期、开花期、结果期等)的形态特征,为精准农业和智能种植提供技术支持。文章提供了完整的代码实现,并讨论了模型优化策略和实际应用场景。关键词:植物生长阶段识别、YOLOv8、目标检测、PyQt5、深度学习。

YOLO 465

【软件系统架构】系列六:系统工程

系统工程是一种跨学科方法论,用于分析、设计、集成和管理复杂系统的全生命周期。其核心特点包括系统性思维、全周期管理、跨学科协作和需求导向。主流采用V模型生命周期,涵盖需求分析、系统设计、实现、测试验证及运维退役等阶段。核心工作方法包括需求工程、系统建模、接口设计、风险管理等。系统工程与项目管理协同,分别侧重技术实现和进度资源管理。应用领域覆盖航天军工、智能制造、智慧城市等。未来将向AI融合、数字孪生、模型驱动工程等方向发展,为复杂系统开发提供系统化协作范式。

moton2017的博客 2257

[JavaScript] 仿京东放大镜案例

实现效果: 案例分析: 整个案例可以分为三个功能模块 第一个模块:鼠标经过小图片盒子,黄色的遮挡层和大图片盒子显示,离开隐藏2个盒子功能 第二个模块:黄色的遮挡层跟随鼠标功能。 第三个模块:移动黄色遮挡层,大图片跟随移动功能。 相关的代码会在最后给大家贴出来,为方便理解先给大家对本例进行一下讲解: 第一部分: preview_img 代表装手机图片的盒子 ,mask代表用来遮罩的淡黄色盒子,big代表用来装放大效果手机图片的大盒子 那么显而易见第一个模块主要就是做一个显示与隐藏的效果 然后重头戏,第二个

qq_49900295的博客 1131

《从底层结构开始学习FPGA》目录与传送门

《从底层结构开始学习FPGA》目录与传送门

孤独的单刀 16万+

用原生js实现放大镜的功能

这是京东上面的放大镜功能的实例,首先说一下放大镜功能的组成结构 包括一张大图片,一张小图片 ,两个div用来实现显示部分的内容; 基本的html样式: 从html中可以看到big这个div包含一个bigimg的子图片 previewimg包含一个名叫mask的子div 这非常重要; 下面是基本的css样式: .preview_wrap { width: 400px; heigh...

kongge123456的博客 2992

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

京东商品的放大镜效果实现(html+css+js)

京东商品首页随便选择一个商品进入到商品详情页,商品放大镜就是如下图所示的效果: 从图中分析可得: (1)首先在鼠标放置在商品上的时候会出现一个黄色的透明遮罩层 (2)遮罩层会随着鼠标的移动一起移动,这里要注意遮罩层的移动范围在图片盒子内部 (3)当出现遮罩层的时候右边同时也会出现一个盒子,盒子里面是放大后的商品图 PS:看起来好像右边盒子里的图片是左边遮罩层所覆盖部分的放大—专业称为“放大镜”效果,但实际上这里是两张图片,一张小图片放在左边的盒子里,一张大图片放在右边的盒子里,遮罩层在左边盒子

Learning_xzj的博客 6835

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

JS实践——放大镜

原理 鼠标在小图片上移动时,通过捕捉鼠标在小图上的位置,定位大图片的相应位置。 思路 首先,我们先理清楚页面元素。 页面元素 容器——demo 小盒子(尺寸与图片一样) 放大镜框 小图片大盒子(尺寸与图片一样) 大图片 事件事件都发生在小盒子上。最简单的是——onmouseover、onmouseout,此时只需要控制放大镜框,以及大容器的显示与隐藏。最复杂的是,onmousemove事件。

lihaoen666的博客 346

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

js放大镜(图片放大)

js图片放大 1.结构部分 <div class="box" id="box"> <div class="small"> //要放大的图片 <img src="image/higher.jpeg" width="350" alt="" /> //放大镜 <div class="mask"></div> </div&g

lancer_sti的博客 854

图片放大镜(有意思的JS 二)

28800秒,给你带来超有意思的放大镜效果

Zhangguohao666的博客 1551

原生JS写放大镜案例

放大镜效果,原生JavaScript实现

m0_62508027的博客 186

基于原生Javascript的放大镜插件的设计和实现

本文主要介绍一个前端放大镜插件的设计和实现,该插件可以将图片的指定区域进行局部放大,插件运行不依赖任何第三方库,可以在Chrome或Edge的常见版本上运行。

weixin_43263355的博客 1088

Formula.js与其他JavaScript计算库对比分析:选择最适合你的Excel公式工具

在JavaScript开发中,处理Excel公式计算是一个常见需求,而Formula.js作为微软Excel公式函数的JavaScript实现,提供了强大的计算能力。本文将从多个角度对比Formula.js与其他主流JavaScript计算库,帮助你找到最适合项目需求的工具。😊 ## Formula.js简介:强大的Excel公式引擎 Formula.js是一个开源的JavaScript库,

gitblog_01063的博客 747
上一篇: CSS实现盒子水平垂直居中的几种优雅方法
下一篇: 尚硅谷Vue尚品汇项目-解决购物车刷新页面后数据渲染失败的问题
noirscent
博客等级 码龄6年 4粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值