原生JavaScript实现淘宝风格放大镜效果教程

作者:窗边听雨

时间:2026-10-23

浏览:72

本文详解如何使用原生JavaScript实现类似淘宝的放大镜效果。通过结合CSS相对定位、鼠标移入移出及移动事件,利用clientX/Y获取坐标,配合offset系列属性计算位移,实现小图遮罩跟随鼠标移动并同步显示大图局部区域的功能。

文章目录

放大镜效果概述

在浏览淘宝、天猫或京东等电商平台时,用户常会注意到一种图片交互效果:当鼠标悬停在商品主图上时,右侧会同步显示一个放大的预览区域,这便是典型的放大镜效果。为了巩固JavaScript基础知识,本文将演示如何利用基础DOM操作和事件处理,复现这一常见的电商交互功能。

核心技术基础

实现该效果主要依赖以下几项核心技术点:

CSS相对定位:需设置元素为position: absolute,以便在父容器内精确定位浮动层。

鼠标交互事件:主要涉及onmouseover(鼠标移入)、onmouseout(鼠标移出)以及onmousemove(鼠标移动)。这些事件通常组合使用,以控制遮罩层的显示、隐藏及跟随行为。

鼠标坐标获取:通过event对象的clientX和clientY属性,分别获取鼠标在视口中的X轴和Y轴坐标。

元素水平偏移量:利用offsetLeft属性,获取当前元素相对于其定位父元素的左侧距离。

元素垂直偏移量:利用offsetTop属性,获取当前元素相对于其定位父元素的顶部距离。

元素实际尺寸:通过offsetWidth和offsetHeight属性,获取元素的实际宽度和高度(不包含滚动条)。

数值范围限制:使用Math.min()和Math.max()函数,确保计算出的坐标或尺寸不超出允许的最大值和最小值范围,防止遮罩或大图移出可视区域。

代码实现

以下是具体的代码实现部分:


<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>放大镜效果</title>
<style type="text/css">
*{
padding: 0;
margin: 0;
}
#demo{
display: block;
width: 400px;
height: 255px;
margin: 50px;
position: relative;
border: 1px solid #ccc;
}
#float-box{
position: relative;
z-index: 1;
}
#small-box{
display: none;
width: 160px;
height: 120px;
position: absolute;
background: #ffffcc;
border: 1px solid #ccc;
filter: alpha(opacity=50);
opacity: 0.5;
cursor: move;
}
#big-box{
display: none;
position: absolute;
top: 0;
left: 460px;
width: 400px;
height: 300px;
overflow: hidden;
border: 1px solid #ccc;
z-index: 1;
 
 
}
#big-box img{
position: absolute;
z-index: 5;
}
 
 
</style>
</head>
<body>
<div id="demo">
<div id="float-box">
<div id="small-box"></div>
<img src="../images/macbook-small.jpg">
</div>
<div id="big-box">
<img src="../images/macbook-big.jpg">
</div>
</div>
<script type="text/javascript">
window.onload = function(){
 
//获取到需要的元素
var demo = document.getElementById('demo');
var smallBbox = document.getElementById('small-box');
var floatBox = document.getElementById('float-box');
var bigBox = document.getElementById('big-box');
var bigBoxImg = bigBox.getElementsByTagName('img')[0];
 
 
floatBox.onmouseover = function(){
smallBbox.style.display = "block";
bigBox.style.display = "block";
}
floatBox.onmouseout = function(){
smallBbox.style.display = "none";
bigBox.style.display = "none";
}
floatBox.onmousemove = function(e){
var _event = e || event;
console.log(_event.clientY);
var l = _event.clientX - demo.offsetLeft - floatBox.offsetLeft - smallBbox.offsetWidth/2;//除2是因为让鼠标点出现在放大遮罩的中心位置
var t = _event.clientY - demo.offsetTop - floatBox.offsetTop - smallBbox.offsetHeight/2;
 
var demoWidth = demo.offsetWidth;
var demoHeight = demo.offsetHeight;
 
 
var smallBboxWidth = smallBbox.offsetWidth;
var smallBboxHeight = smallBbox.offsetHeight;
//鼠标可以移动的最大XY的距离
var maxX = demoWidth - smallBboxWidth;
var maxY = demoHeight - smallBboxHeight;
 
 
l = Math.min(maxX,Math.max(0,l));
t = Math.min(maxY,Math.max(0,t));
smallBbox.style.left = l +"px";
smallBbox.style.top = t +"px";
 
 
var percentX = l / (floatBox.offsetWidth - smallBboxWidth);//求出小图遮罩的坐标占可移动区域的比例
var percentY = t / (floatBox.offsetHeight - smallBboxHeight);
 
 
bigBoxImg.style.left = -percentX *(bigBoxImg.offsetWidth - bigBox.offsetWidth) +"px";//大图对的移动方向和小图遮罩的移动方向相反
bigBoxImg.style.top = -percentY*(bigBoxImg.offsetHeight - bigBox.offsetHeight)+"px";
 
}
}
</script>
</body>
</html>

本文介绍了上述核心逻辑,希望能为读者的学习提供参考。如有更多疑问,欢迎继续支持本站内容。

实用工具推荐

电子包浆

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

使用 ›
图片压缩

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

使用 ›
相关文章