使用html和js实现的一个简单小练习购物车的放大镜功能,鼠标移入展示图区域,出现蒙版和大图,鼠标移动同时右边的大图也会移动呈现出放大的效果。
依旧使用的是DOM2事件代理,详细的解释和代码步骤我都注释在下面的代码中的,请君一阅。
【注:仅作自己查看和分享学习之用】
案例图:
代码如下:
<!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>放大镜</title>
</head>
<style>
body {
margin: 0;
padding: 0;
}
article {
width: 880px;
margin: 100px auto;
display: flex;
}
section {
width: 430px;
height: 430px;
border: 3px solid yellowgreen;
}
#container>div:nth-child(1) {
height: 430px;
position: relative;
margin-bottom: 10px;
}
#mask {
position: absolute;
background-color: rgba(98, 255, 0, 0.5);
display: none;
}
img {
height: 100px;
width: 100px;
display: inline-block;
border: 1px solid #d0d0d0;
}
#bigTu {
display: none;
}
</style>
<body>
<article>
<section id="container">
<!-- 展示中图 -->
<div>
<!-- 蒙版 -->
<aside id="mask"></aside>
</div>
<!-- 展示小图 -->
<div></div>
</section>
<!-- 展示大图片 -->
<section id="bigTu"></section>
</article>
<script src="fang.js"></script>
</body>
</html>
/**需求:
1.鼠标移入图片切换
2.鼠标移入出现绿色蒙版,蒙版跟随鼠标移动
3.蒙版对应的区域放大出现在图片右边
*/
let imgArr = [
{ small: "./img/imgA_s.jpg", middle: "./img/imgA_m.jpg", large: "./img/imgA_l.jpg" },
{ small: "./img/imgB_s.jpg", middle: "./img/imgB_m.jpg", large: "./img/imgB_l.jpg" },
{ small: "./img/imgC_s.jpg", middle: "./img/imgC_m.jpg", large: "./img/imgC_l.jpg" },
]
//获取节点
//获取中图节点
let divM = document.getElementsByTagName("div")[0];
//获取小图盒子节点
let divS = document.getElementsByTagName("div")[1];
//获取大图节点
let bigTu = document.getElementById("bigTu");
//获取蒙版节点
let mask = document.getElementById("mask");
//渲染大、中图和小图
function render() {
//渲染中图
divM.style.backgroundImage = `url(${imgArr[0].middle})`;
divM.style.backgroundSize = "100% 100%";
//渲染大图
bigTu.style.backgroundImage = `url(${imgArr[0].large})`;
bigTu.style.backgroundRepeat = "no-repeat";
//渲染小图
let str = "";
imgArr.forEach((item, index) => {
str += `
<img src="${item.small}" alt="" data-index=${index}>
`;
});
divS.innerHTML = str;
}
render();
//获取所有的小图节点
let smImg = document.getElementsByTagName("img");
//鼠标移入哪张小图,就更换图片
divS.addEventListener("mouseover", function (e) {
let event = e || window.event;
if (event.target.nodeName == "IMG") {
//将所有的小图边框恢复成默认样式
[...smImg].forEach(node => node.style.border = "1px solid #d0d0d0");
//获取小图当前的下标
let index = event.target.dataset.index;
//只有移入才会改变小图边框
event.target.style.cssText = `
border: 2px solid red;
`;
//中图区域更换图片
divM.style.backgroundImage = `url(${imgArr[index].middle})`;
//大图区域更换图片
bigTu.style.backgroundImage = `url(${imgArr[index].large})`;
}
});
//鼠标移入中图,显示蒙版和大图
//因为 mouseover、mouseout对事件源和其子后代元素都有效,而 mouseenter、mouseleave只对事件源生效;
//我们把事件绑定在中图区域身上,所以使用mouseover这一组才合适。
divM.addEventListener("mouseover", function () {
bigTu.style.display = "block";
mask.style.display = "block";
//设置蒙版尺寸,大图 800*800,中图 430*430
mask.style.width = 430 / (800 / 430) + "px";
mask.style.height = 430 / (800 / 430) + "px";
//蒙版移动
mask.addEventListener("mousemove", moveMask);
});
//蒙版移动函数
function moveMask(e) {
let event = e || window.event;
//让鼠标始终位于元素(即蒙版)中心点
//蒙版水平移动的距离 = 鼠标距离视口左侧的距离 -父元素(即中图)距离视口左侧的距离 - 蒙版尺寸的一半
let maskX = event.clientX - divM.offsetLeft - mask.clientWidth / 2;
//蒙版垂直移动的距离 = 鼠标距离视口右侧的距离 -父元素(即中图)距离视口右侧的距离 - 蒙版尺寸的一半
let maskY = event.clientY - divM.offsetTop - mask.clientHeight / 2;
//蒙版水平移动的最大距离 = 父元素的宽 - 蒙版的宽
let maxX = divM.clientWidth - mask.clientWidth;
//蒙版垂直移动的最大距离 = 父元素的高 - 蒙版的高
let maxY = divM.clientHeight - mask.clientHeight;
if (maskX <= 0) {
maskX = 0;
} else if (maskX >= maxX) {
maskX = maxX;
}
if (maskY <= 0) {
maskY = 0;
} else if (maskY >= maxY) {
maskY = maxY;
}
console.log(maskX, maskY);
mask.style.cssText = `
left:${maskX}px;
top:${maskY}px;
`;
//当蒙版移动时,大图要变化,大图800*800,中图430*430
//因为大图是背景图进行移动,所以按照雪碧图的规则来,X和Y值皆为负值
//大图移动的水平距离 = 中图移动的水平距离 * 大图与中图之间的比例
let bigX = -maskX * (800 / 430);
//大图移动的垂直距离 = 中图移动的垂直距离 * 大图与中图之间的比例
let bigY = -maskY * (800 / 430);
bigTu.style.backgroundPositionX = bigX + "px";
bigTu.style.backgroundPositionY = bigY + "px";
}
//鼠标移出中图区域,蒙版和大图消失
divM.addEventListener("mouseout", function () {
bigTu.style.display = "none";
mask.style.display = "none";
});