放大镜特效

放大镜特效,在电商网站是比较常见的。先贴出我的代码。

CSS部分

<style>
		* {
			padding: 0;
			margin: 0;
		}

		.wrap {
			width: 880px;
			border: 1px solid black;
			margin: 50px auto;
		}

		.wrap>div {
			width: 430px;
			height: 430px;
			border: 1px solid #eee;
		}

		.middleImg {
			float: left;
			background: url("./images/imgA_2.jpg") no-repeat;
			position: relative;
		}

		.largeImg {
			float: right;
			background: url("./images/imgA_3.jpg") no-repeat;
			display: none;
		}

		.smallImg {
			clear: both;
			list-style: none;
			display: flex;
		}

		.smallImg li {
			margin: 20px 10px;
		}

		.smallImg img {
			vertical-align: top;
			border: 2px solid transparent;
		}

		.enlarge {
			background: url("./images/bg.png");
			width: 231px;
			height: 231px;
			position: absolute;
			top: 0;
			left: 0;
			display: none;
		}
	</style>

  HTML部分

<div class="wrap">
		<!-- 左上正常显示的图片 -->
		<div id="middleImg" class="middleImg">
			<!-- 遮罩层 -->
			<div class="enlarge" id="enlarge"></div>
		</div>
		<!-- 右边放大的图片 -->
		<div id="largeImg" class="largeImg"></div>
		<!-- 下面的缩略图 -->
		<ul id="smallImg" class="smallImg"></ul>
	</div>

  JS部分

// 初始化图片数据
let imgs = {
	small: ["imgA_1.jpg", "imgB_1.jpg", "imgC_1.jpg"],
	middle: ["imgA_2.jpg", "imgB_2.jpg", "imgC_2.jpg"],
	large: ["imgA_3.jpg", "imgB_3.jpg", "imgC_3.jpg"]
}

handleSmall(); // 操作缩略图
handleMiddle(); // 操作展示图

// 用于操作缩略图的函数
function handleSmall() {
	// 为id为smallImg的ul动态的添加li
	smallImg.innerHTML = imgs.small.map((item, index) => {
		return `<li><a href="#"><img src="./images/${item}" _id="${index}" class="img"/></a></li>`;
	}).join("");
	let imgArr = document.getElementsByClassName("img"); // 获取所有的img元素集合
	imgArr[0].style.borderColor = "black"; // 为第一个缩略图添加border
	// 为id为smallImg的ul添加mouseover事件
	smallImg.addEventListener("mouseover", (e) => {
		// 如果是在缩略图上面移动
		if (e.target.nodeName === "IMG") {
			// 首先将所有缩略图的border去除掉
			for (let i = 0; i < imgArr.length; i++) {
				imgArr[i].style.borderColor = "transparent";
			}
			e.target.style.borderColor = "black"; // 然后将当前鼠标所在的缩略图上面添加上border
			let i = e.target.getAttribute("_id"); // 获取到该图片的id
			// 改变左上方图片以及右边大图的链接
			middleImg.style.background = `url("./images/${imgs.middle[i]}") no-repeat`
			largeImg.style.background = `url("./images/${imgs.large[i]}") no-repeat`
		}
	}, false);
}

// 给左上方的图片添加鼠标移入移出事件的函数
function handleMiddle() {
	middleImg.addEventListener("mousemove", (e) => {
		// 鼠标移动时 右边大图以及遮罩层显示
		largeImg.style.display = "block";
		enlarge.style.display = "block";
		// 鼠标当对于文档显示区的坐标
		let mouseX = e.clientX;
		let mouseY = e.clientY;
		// middleImg 相对于文档显示区的坐标
		let eleX = middleImg.offsetLeft;
		let eleY = middleImg.offsetTop;
		let moveX = mouseX - eleX - enlarge.offsetWidth / 2;
		let moveY = mouseY - eleY - enlarge.offsetHeight / 2;
		// 边界判断
		if (moveX <= 0) {
			moveX = 0;
		} else if (moveX >= middleImg.clientWidth - enlarge.offsetWidth) {
			moveX = middleImg.clientWidth - enlarge.offsetWidth;
		}
		if (moveY <= 0) {
			moveY = 0;
		} else if (moveY >= middleImg.clientHeight - enlarge.offsetHeight) {
			moveY = middleImg.clientHeight - enlarge.offsetHeight
		}
		// 动态修改遮罩层的位置
		enlarge.style.left = moveX + "px";
		enlarge.style.top = moveY + "px";
		// 动态修改大图的显示位置
		largeImg.style.backgroundPositionX = -moveX * (800 / 430) + "px";
		largeImg.style.backgroundPositionY = -moveY * (800 / 430) + "px";
	}, false);

	// 鼠标移出时 右边大图以及遮罩层不显示
	middleImg.addEventListener("mouseout", () => {
		largeImg.style.display = "none";
		enlarge.style.display = "none";
	}, false);
}

  在这个程序中,需要注意的是在确定鼠标距离事件源的位置,要减去离整个clienx和clientY的距离后,要再减去遮罩层的一半,如果不这样,鼠标定位会在左上角,不符合视觉审美效果。  

  其次,应该 注意,右侧大图的位置,是根据左侧小图与大图的倍数来确定 的。

  如有疑问,请留言 。

posted @ 2018-10-14 20:43  smuwgeg  阅读(416)  评论(0编辑  收藏  举报