效果图如下:
html文件如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
body {
height: 2000px;
}
ul {
list-style: none;
}
img {
width: 100%;
height: 100%;
display: block;
}
#main {
width: 1000px;
margin: 50px;
position: relative;
}
#main .show {
width: 400px;
height: 400px;
border: 2px solid red;
position: relative;
}
#main .glass {
width: 200px;
height: 200px;
position: absolute;
left: 0;
top: 0;
background: yellowgreen;
opacity: 0.5;
display: none;
}
#main .list {
width: 100%;
display: flex;
justify-content: flex-start;
align-items: center;
}
#main .list li {
margin: 20px 20px 0 0;
width: 80px;
height: 80px;
}
#main .list li.active {
border: 2px solid red;
}
#main .scale {
width: 500px;
height: 500px;
border: 2px solid black;
background: url(./images/1.big.jpg) no-repeat 0 0;
background-size: 1000px;
margin-left: 20px;
position: absolute;
left: 450px;
top: 0;
display: none;
}
</style>
</head>
<body>
<div id="main">
<!-- 图片显示区域 -->
<div class="show">
<img src="./images/1.jpg" alt="">
<!-- 选中区域 -->
<div class="glass"></div>
</div>
<!-- 图片列表区域 -->
<ul class="list">
<li class="active"><img src="./images/1.small.jpg" alt=""></li>
<li><img src="./images/2.small.jpg" alt=""></li>
</ul>
<!-- 放大区域 -->
<div class="scale"></div>
</div>
<script src="./面向对象.js"></script>
<script>
let oDiv = document.querySelector("#main");
const arr = [
{ big: '1.big.jpg', normal: '1.jpg', small: '1.small.jpg' },
{ big: '2.big.jpg', normal: '2.jpg', small: '2.small.jpg' },
]
const magnifier = new Magnifier(oDiv, arr);
magnifier.init();
</script>
</body>
</html>
js代码如下:
class Magnifier {
constructor(ele, arr) {
this.ele = ele;
this.arr = arr; // 存储图片路径
this.list = ele.querySelectorAll('.list li');
this.show = ele.querySelector(".show");
this.img = this.show.querySelector('img'); // 获取show中的图片
this.glass = ele.querySelector(".glass");
this.scale = ele.querySelector(".scale"); // 获取放大区域标签
this.backSize = parseInt(window.getComputedStyle(this.scale).backgroundSize); // 获取最大图片大小
this.showSize = parseInt(window.getComputedStyle(this.show).width); // 获取最大图片大小
}
// 初始化函数,在外只需要调用这个就行
init() {
// 调用鼠标移入移出函数
this.mouseOverOut();
// 移动放大镜函数
this.move();
}
// 鼠标移入移出时间
mouseOverOut() {
// 鼠标移入正常图片
this.show.addEventListener('mouseover', () => {
this.glass.style.display = "block";
this.scale.style.display = "block";
});
// 鼠标移出正常图片
this.show.addEventListener('mouseout', () => {
this.glass.style.display = "none";
this.scale.style.display = "none";
});
// 遍历小图片列表,添加鼠标移入移出事件
this.list.forEach((val, key) => {
val.addEventListener('mouseover', () => {
this.list.forEach((v, k) => {
// 先清空样式
v.className = "";
});
// 再给点击的小图片加样式
val.className = "active";
// 改变图片路径
this.img.src = `./images/${this.arr[key].normal}`;
// 改变背景图片
this.scale.style.background = `url(./images/${this.arr[key].big})`;
// 改变背景图片大小,不写会被覆盖掉,大图会不按放大镜比例显示大小
this.scale.style.backgroundSize = this.backSize + 'px';
});
});
}
// 移动放大镜函数
move() {
// 只在图片区域中移动,移出就不会有效果
this.show.addEventListener('mousemove', (e) => {
// 没有滚动,用e.clientX和e.pageX一样,有滚动时,看是不是固定定位,固定不变就用e.clientX,相对于视窗窗口
// 得到移动放大镜的中心点坐标
let x = e.pageX - this.ele.offsetLeft - this.ele.clientLeft - this.glass.clientWidth / 2;
let y = e.pageY - this.ele.offsetTop - this.ele.clientTop - this.glass.clientHeight / 2;
// 判断边界值
if (x < 0) {
x = 0;
}
if (y < 0) {
y = 0;
}
if (x > this.show.clientWidth - this.glass.clientWidth) {
x = this.show.clientWidth - this.glass.clientWidth;
}
if (y > this.show.clientHeight - this.glass.clientHeight) {
y = this.show.clientHeight - this.glass.clientHeight;
}
// 将数值传给放大镜
this.glass.style.left = `${x}px`;
this.glass.style.top = `${y}px`;
// 同时改变背景图位置,移动大小与放大镜为比例关系,此处400/1600为1:4
let bx = this.backSize * x / this.showSize;
let by = this.backSize * y / this.showSize;
// 改变背景图位置
this.scale.style.backgroundPosition = `-${bx}px -${by}px`;
});
}
}