面向对象封装放大镜js代码
<!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;
}
.header {
height: 200px;
background-color: #ccc;
}
.container {
width: 980px;
margin: 0 auto;
}
ul {
list-style: none;
}
.fdj {
width: 350px;
position: relative;
}
.fdj1 {
width: 400px;
position: relative;
}
.fdj2 {
width: 200px;
position: relative;
}
</style>
</head>
<body>
<div class="header">
<div class="container"></div>
</div>
<div class="content">
<div class="container">
<div class="fdj">
</div>
<hr>
<div class="fdj1">
</div>
<hr>
<div class="fdj2">
</div>
</div>
</div>
<script>
// 第一步:把要书写的目标看作一个整体
// 第二步:分析这个整体应当有什么属性和方法
// 容器\图片数组\小图\图片列表\大图\镜片...
// 第三步:定义类和属性
function Zoom(container, imgArr) {
//整个放大镜的容器
this.container = container;
//图片的数组
this.imgArr = imgArr;
//创建一张小图
this.smallImg = document.createElement("img");
//创建一张大图
this.bigImg = document.createElement("img");
//创建图片列表
this.ul = document.createElement("ul");
//创建镜片
this.glass = document.createElement("div");
//接受图片列表中有几个li 以便以后使用
this.lis = [];
//大图小图的比例
this.r = 0.5;
}
Zoom.prototype = {
//将构造函数传递进来
constructor: Zoom,
//基本架构
render() {
//创建小图的容器
var smallContainer = document.createElement('div');
//创建大图容器
var bigContainer = document.createElement('div');
//将第一张大图小图的地址给到各自的img元素节点
this.smallImg.src = this.imgArr[0].smallImgPath;
this.bigImg.src = this.imgArr[0].bigImgPath;
//将小图添加到小图的容器中
smallContainer.appendChild(this.smallImg);
//将大图添加到大图的容器中
bigContainer.appendChild(this.bigImg);
//将大图、小图、图片列表ul的容器给到大的容器
this.container.appendChild(smallContainer);
this.container.appendChild(bigContainer);
this.container.appendChild(this.ul);
//将放大镜给到小图的容器中
smallContainer.appendChild(this.glass);
//循环img数组并按照有多少个img就生成多少个li
this.imgArr.forEach(item => {
var li = document.createElement('li');
var img = document.createElement('img');
//给每一个li中的img赋予一个图片地址
img.src = item.iconPath;
//上树
li.appendChild(img);
this.ul.appendChild(li);
this.lis.push(li);
})
},
//添加样式
addStyle() {
//添加小图样式
//得到小图和大图的容器
var smallContainer = this.smallImg.parentNode;
var bigContainer = this.bigImg.parentNode;
//console.log(bigContainer);
// console.log(smallContainer);
//赋予小图的容器大小
smallContainer.style.width = "100%";
smallContainer.style.height = "100%";
smallContainer.style.backgroundColor = 'red';
// this.smallImg.style.display = "block";
// this.smallImg.style.width = "100%";
// this.smallImg.style.height = "100%";
//定义小图的样式
var smallImg = {
width: '100%',
height: '100%',
display: 'block'
}
for (var i in smallImg) {
this.smallImg.style[i] = smallImg[i];
}
//console.log(smallContainer.clientHeight);
//定义大图的容器的样式
var bigImg = {
width: smallContainer.clientWidth * 1.54 + 'px',
height: smallContainer.clientWidth * 1.54 + 'px',
position: 'absolute',
left: '110%',
top: 0,
overflow: 'hidden'
}
for (var i in bigImg) {
// console.log(bigImg[i]);
bigContainer.style[i] = bigImg[i];
}
//定义放大镜的样式
var glass = {
width: smallContainer.clientWidth * this.r + 'px',
height: smallContainer.clientWidth * this.r + 'px',
position: 'absolute',
left: 0,
top: 0,
backgroundColor: 'rgba(255,0,0,0.5)'
}
for (var i in glass) {
// console.log(bigImg[i]);
this.glass.style[i] = glass[i];
}
//定义图片列表的样式
var ul = {
display: 'flex',
justifyContent: 'space-around',
paddingTop: '10px'
}
for (var i in ul) {
this.ul.style[i] = ul[i]
}
//给li中的图增加边框
this.lis.forEach(item => {
item.style.border = "2px solid transparent"
})
//给大图样式 增加定位
var bigImg = {
// width: '100%',
// height: '100%',
position: 'absolute',
top: 0,
left: 0
}
for (var i in bigImg) {
this.bigImg.style[i] = bigImg[i]
}
},
//添加事件
addEvent() {
//给每个li绑定事件
this.lis.forEach((item, index) => {
//当鼠标移入li时
item.addEventListener("mouseenter", () => {
// console.log(this.imgArr);
//给大图和小图重新定义图片的路径
this.smallImg.src = this.imgArr[index].smallImgPath;
this.bigImg.src = this.imgArr[index].bigImgPath;
//排他法
this.lis.forEach((item, index) => {
item.style.borderColor = 'transparent'
})
//给点击到的li一个边框颜色
this.lis[index].style.borderColor = 'red'
}
)
})
//鼠标移入小图的容器时 移动放大镜
this.smallImg.parentNode.addEventListener("mousemove", (e) => {
// console.log(1);
//得到最大的容器距离页面的距离
let obj = Zoom.offset(this.container);
// console.log(obj.left, obj.top);
//鼠标在页面中的位置减元素的位置减放大镜的大小除以2 就是放大镜的位置
let x = e.pageX - obj.left - this.glass.clientWidth / 2;
let y = e.pageY - obj.top - this.glass.clientHeight / 2
if (x < 0) {
x = 0
} else if (x > this.smallImg.parentNode.clientWidth - this.glass.clientWidth) {
x = this.smallImg.parentNode.clientWidth - this.glass.clientWidth;
}
if (y < 0) {
y = 0
} else if (y > this.smallImg.parentNode.clientHeight - this.glass.clientHeight) {
y = this.smallImg.parentNode.clientHeight - this.glass.clientHeight;
}
this.glass.style.left = x + 'px';
this.glass.style.top = y + 'px';
let r = (this.smallImg.clientWidth * this.r / (this.bigImg.width - this.bigImg.parentNode.clientWidth));
this.bigImg.style.left = -x / r + 'px';
this.bigImg.style.top = -y / r + 'px';
})
}
}
Zoom.offset = function(dom) {
// 定义两个变量
var left = 0;
var top = 0;
// 第一次不应该把自己的边框算进去
left = dom.offsetLeft;
top = dom.offsetTop;
// 为了兼容性考虑,IE8要单独处理
// 检测window.navigator.userAgent这个字符串里面是否包含"MSIE 8"
// 如果包含就说明是IE 如果不包含就说明不是IE
var isIE8 = false;
if (window.navigator.userAgent.indexOf("MSIE 8") != -1) {
isIE8 = true;
}
// 让自己指向上一层
dom = dom.offsetParent;
// 而且因为dom没有直接获取到页面的属性所以只能一层一层的往上找
while (dom != document.body) {
// 如果是IE8 不需要加 clientTop clientLeft
if (isIE8) {
// 累加每一层的offsetLeft
left += dom.offsetLeft
// 累加每一层的offsetTop
top += dom.offsetTop
} else {
// 累加每一层的offsetLeft 和clientLeft
left += dom.offsetLeft + dom.clientLeft;
// 累加每一层的offsetTop 和clientTop
top += dom.offsetTop + dom.clientTop;
}
// 让dom指向上一层
dom = dom.offsetParent;
}
return {
left: left,
top: top
}
}
var fdj = document.querySelector('.fdj');
var fdj1 = document.querySelector('.fdj1');
var fdj2 = document.querySelector('.fdj2');
let imgArr = [{
iconPath: "./images/icon01.jpg",
smallImgPath: "./images/small01.jpg",
bigImgPath: "./images/big01.jpg"
}, {
iconPath: "./images/icon02.jpg",
smallImgPath: "./images/small02.jpg",
bigImgPath: "./images/big02.jpg"
}, {
iconPath: "./images/icon03.jpg",
smallImgPath: "./images/small03.jpg",
bigImgPath: "./images/big03.jpg"
}, ];
let z = new Zoom(fdj, imgArr);
z.render();
z.addStyle();
z.addEvent();
let z1 = new Zoom(fdj1, imgArr);
z1.render();
z1.addStyle();
z1.addEvent();
let z2 = new Zoom(fdj2, imgArr);
z2.render();
z2.addStyle();
z2.addEvent();
</script>
</body>
</html>