35放大镜
一、使用面向过程完成放大镜
结构
<div class="big">
<div class="left">
<!--需要修改自己的照片路径-->
<img src="images/img.webp" alt="">
<div class="move"></div>
</div>
<div class="right">
<!--需要修改自己的照片路径-->
<img src="images/img.webp" alt="">
</div>
</div>
样式
* {
margin: 0;
padding: 0;
}
.big {
width: 900px;
height: 400px;
margin: 100px auto;
display: flex;
}
.left {
width: 400px;
height: 400px;
margin-right: 100px;
position: relative;
}
.left img {
width: 400px;
height: 400px;
}
.move {
width: 100px;
height: 100px;
background: rgba(0, 0, 0, 0.5);
position: absolute;
display: none;
cursor:move;
}
.right {
width: 400px;
height: 400px;
overflow: hidden;
position: relative;
}
.right img {
width: 1600px;
height: 1600px;
position: relative;
display: none;
}
JavaScript
//获取节点
var left = document.querySelector(".left")
var right = document.querySelector(".right")
var move = document.querySelector(".move")
var img = document.querySelector(".right img")
//鼠标移入左边盒子的事件
left.onmousemove = function (e) {
//event兼容写法
e = e || window.event
//隐藏的遮罩层和右边的大图片显示
move.style.display = "block"
img.style.display = "block"
//鼠标距离左边盒子的左边和上边距离
var x = e.pageX - left.offsetLeft
var y = e.pageY - left.offsetTop
//要让鼠标在遮罩层的中间,需要在水平方向遮罩层宽的一半,并且让遮罩层不能离开左边盒子的最左边和最右边
move.style.left = x < move.offsetWidth / 2 ? 0 : x > left.offsetWidth - move.offsetWidth / 2 ? left
.offsetWidth - move.offsetWidth + "px" : x - move.offsetWidth / 2 + "px"
//要让鼠标在遮罩层的中间,还需要在垂直方向遮罩层高的一半,并且让遮罩层不能离开左边盒子的最上边和最下边
move.style.top = y < move.offsetHeight / 2 ? 0 : y > left.offsetHeight - move.offsetHeight / 2 ? left
.offsetHeight - move.offsetHeight + "px" : y - move.offsetHeight / 2 + "px"
//右边盒子里面的大图片是左边盒子里面小盒子宽高的4倍,所以需要移动的是遮罩层的4倍,且移动方向都与默认移动方向相反,所以取负值
img.style.left = -parseFloat(move.style.left) * 4 + "px"
img.style.top = -parseFloat(move.style.top) * 4 + "px"
//鼠标移出遮罩层的事件
move.onmouseout = function () {
//遮罩层和右边图片的大图片隐藏
move.style.display = "none"
img.style.display = "none"
//清除鼠标移出遮罩层的事件
move.onmouseout = null
}
}
二、使用面向对象完成放大镜
结构和样式不变
JavaScript
//构造函数Zoom
function Zoom(e1, e2, e3, e4) {
//获取节点
this.left = document.querySelector(e1)
this.right = document.querySelector(e2)
this.move = document.querySelector(e3)
this.img = document.querySelector(e4)
//获取原型对象init
this.init()
}
//创建原型对象init
Zoom.prototype.init = function () {
//获取原型对象moves
this.moves()
}
//创建原型对象moves
Zoom.prototype.moves = function () {
//移入左边盒子的事件
//使用箭头函数,方便里面使用this,箭头函数没有this指向,所以里面出现的this会在上一级查找
//如果使用匿名函数,里面的this指向的是事件源,也就是左边盒子节点
this.left.onmousemove = (e) => {
//event兼容写法
e = e || window.event
//隐藏的遮罩层和右边的大图片显示
this.move.style.display = "block"
this.img.style.display = "block"
//鼠标距离左边盒子的左边和上边距离
var x = e.pageX - this.left.offsetLeft
var y = e.pageY - this.left.offsetTop
//要让鼠标在遮罩层的中间,需要在水平方向遮罩层宽的一半,并且让遮罩层不能离开左边盒子的最左边和最右边
this.move.style.left = x < this.move.offsetWidth / 2 ? 0 : x > this.left.offsetWidth - this.move
.offsetWidth / 2 ? this.left
.offsetWidth - this.move.offsetWidth + "px" : x - this.move.offsetWidth / 2 + "px"
//要让鼠标在遮罩层的中间,还需要在垂直方向遮罩层高的一半,并且让遮罩层不能离开左边盒子的最上边和最下边
this.move.style.top = y < this.move.offsetHeight / 2 ? 0 : y > this.left.offsetHeight - this
.move.offsetHeight / 2 ? this.left
.offsetHeight - this.move.offsetHeight + "px" : y - this.move.offsetHeight / 2 + "px"
//右边盒子里面的大图片是左边盒子里面小盒子宽高的4倍,所以需要移动的是遮罩层的4倍
//移动方向都与默认移动方向相反,所以取负值
this.img.style.left = -parseFloat(this.move.style.left) * 4 + "px"
this.img.style.top = -parseFloat(this.move.style.top) * 4 + "px"
}
//获取原型对象out
this.out()
}
//创建原型对象out
Zoom.prototype.out = function () {
//移出左边盒子的事件
//使用箭头函数,理由和上面移入左边盒子一样
this.move.onmouseout = () => {
//遮罩层和右边图片的大图片隐藏
this.move.style.display = "none"
this.img.style.display = "none"
}
}
//构造函数Zoom实例化
//如果有其他需要使用的地方,直接修改实例化的参数
//例如有相应的样式和结构后直接使用new Zoom(".left2", ".right2", ".move2", ".right2 img"),
//而不需要修改构造函数和圆形函数里面的任何东西
new Zoom(".left", ".right", ".move", ".right img")