js中的放大镜效果

在电商中,放大镜效果是很常见的,如下图所示:

当鼠标悬浮时,遮罩所在区域在右侧进行放大。
在动手写之前,我们要先理清思路,分析需求,所需知识点,再将每一块进行组装,最后进行功能的完善。

首先,需求分析:

  • 打开页面是看到只有一张图片
  • 鼠标悬浮在图片上上时遮罩和右侧图片显示出来
  • 遮罩随着鼠标的移动而移动
  • 右侧图片随着遮罩的移动而移动

其实,想此类两个图片在不同位置,一般都是多图片进行配合运动形成的效果。
本案例中左侧使用的是小图片,右侧使用的是大图片。

所需知识点:

  • 元素的隐藏和显示 display:none / block
  • 右侧大图片只有部分显示,所有需要溢出隐藏 overflow:hidden
  • 遮罩和大图片需要移动,所有要用到定位。position : absolute;

下面我们来写代码:

<!DOCTYPE html>
<html lang="zh">
<head>
	<title>放大镜</title>
	<style>
		/* 预定义样式 */
		*{
			padding: 0;
			margin: 0;
		}
		/* 处理容器 */
		#box{
			margin: 100px 200px;
		}
		#box,#d_small{
			width: 400px;
			height: 240px;
			display: inline-block;
			border: 1px sold red;
			position: relative;	
		}
		/* 大图片的容器 */
		/* 因为遮罩是正方形,所有大图片的显示部分也要是正方形,这样视觉效果才会更好 */
		#d_big {
			width: 240px;
			height: 240px;
			position: absolute;
			top:0;
			left: 400px;
			overflow: hidden;
			display: none;
			border: 1px solid red;
		}
		/* 左侧小图片*/
		#d_small img{
			width: 400px;
			height: 240px;
			vertical-align: top;
		}
		/* 大图片的尺寸和小图片宽高比例要一直,避免穿帮 */
		#d_big img{
			width: 800px;
			height: 480px;
			vertical-align: top;
			position: absolute;
			top:0;
			left:0;
		}
		/* 遮罩样式 */
		#mask{
			width: 100px;
			height: 100px;
			background-color: rgba(225,225,250,.6);
			position: absolute;
			top: 0;
			left: 0;
			display: none;
		}	
	</style>
</head>
<body>
	<div id="box">
		<div id="d_small">
			<img src="img/1.jpg">
			<div id="mask"></div>
		</div>
		<div id="d_big"><img src="img/2.jpg"></div>
		
	</div>
</body>
</html>

下面来写一下js

<script>
	// 获取节点
	var small = document.getElementById("d_small");	//获取小图片的容器
	var smallImage = small.children[0];	//获取小图片
	var mask = small.children[1];	//获取遮罩
	var big = document.getElementById("d_big");	//获取大图片的容器
	var bigImage = big.children[0];	//获取大图片
	// 绑定鼠标事件
	// 鼠标悬浮在小图片时,让遮罩和大图片显示处理
	small.onmouseover = function(){
		mask.style.display = "block";
		big.style.display = "block";	
	}
	// 鼠标移出时再消失
	small.onmouseout = function(){
		mask.style.display = "none";
		big.style.display = "none";	
	}
	// 鼠标移动时,遮罩跟着移动,并且大图片跟着以相同比例移动
	// 绑定鼠标移动事件
	// Event 是一个事件对象,当一个事件发生后,和当前事件发生相关的详细信息会被临时存储到一个指定的地方,也就是event对象,
	
	// 声明一个变量用来储存遮罩的坐标位置
	var x = 0;
	var y = 0;
	small.onmousemove = function(event){
		// 作兼容
		var event = event || window.event;
		
		// 遮罩中心点X坐标 = 鼠标X坐标 - 定位的父级元素的左偏移量 - 1/2的遮罩的宽度
		var x = event.clientX - this.offsetParent.offsetLeft - mask.offsetWidth / 2;
		var y = event.clientY - this.offsetParent.offsetTop - mask.offsetHeight / 2;
		// console.log(x,y);
		// 用来判断遮罩达到小图片边界是的状况,以免遮罩移出小图片框
		if(x < 0){
			x = 0
		}else if (x > small.offsetWidth - mask.offsetWidth){
			x = small.offsetWidth - mask.offsetWidth;
		};
		if(y < 0){
			y = 0
		}else if (y > small.offsetHeight - mask.offsetHeight){
			y = small.offsetHeight - mask.offsetHeight;
		};
		// 遮罩的动态定位
		mask.style.left = x + "px";
		mask.style.top = y + "px";
		// 设置右侧大图片的移动(大图片的移动 = 大图片与小图片的比例 * 遮罩的移动)
		// a,b为大图片想做和向上的偏移量
		var a = -x * bigImage.offsetWidth / smallImage.offsetWidth; 
		var b = -y * bigImage.offsetHeight / smallImage.offsetHeight; 
		
		// 为防止右侧和下侧出现空白区域,进行一个判断
		if(a < -(bigImage.offsetWidth - big.offsetWidth)){
			bigImage.style.left =- (bigImage.offsetWidth - big.offsetWidth )+ "px";
		}else{
			bigImage.style.left = -x * bigImage.offsetWidth / smallImage.offsetWidth + \'px\';
		}		
		if(b < -(bigImage.offsetHeight - big.offsetHeight)){
			bigImage.style.top = -(bigImage.offsetHeight - big.offsetHeight) + "px";
		}else{
			bigImage.style.top = -y * bigImage.offsetHeight / smallImage.offsetHeight + \'px\';
		}		
	}

</script>

版权声明:本文为hubufen原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/hubufen/p/10902843.html