放大镜案例
实现效果如下图所示:
第一步:结构分析
结构分析
1-一个大盒子 div.box
2-一个放中等图片的盒子 div.middleBox
一张中等图片
一个遮罩层 div.shade
3-一个放小图片的盒子 div.smallBox
两张小图片
4-一个放大图的盒子div.bigBox
结构代码:
<div class="box">
<div class="middleBox">
<img src="../img/middle1.jpg" alt="">
<div class="shade"></div>
</div>
<div class="smallBox">
<img src="../img/small1.jpg" middleImg="../img/middle1.jpg" bigImg="../img/big1.jpg" class="active">
<img src="../img/small2.jpg" middleImg="../img/middle2.jpg" bigImg="../img/big2.jpg">
</div>
<div class="bigBox"></div>
</div>
样式:
<style>
*{margin: 0; padding: 0;}
.box{
width: 402px;
position: relative;
margin: 0 auto;
}
.middleBox{
width: 400px;
height: 400px;
border: 1px solid #000;
}
.middleBox>img{
width: 400px;
height: 400px;
}
.middleBox>.shade{
width: 200px;
height: 200px;
background-color: yellow;
opacity: .5;
position: absolute;
top: 0px;
left: 0px;
cursor: move;
}
.smallBox{
margin-top: 15px;
}
.smallBox>img{
width: 50px;
height: 50px;
border: 1px solid #000;
margin-left: 5px;
}
.smallBox>img.active{
border: 3px solid red;
}
.bigBox{
width: 400px;
height: 400px;
border: 1px solid #000;
position: absolute;
top: 0px;
left: 105%;
background-image: url("../img/big1.jpg");
background-repeat: no-repeat;
background-position: 0 0;
background-size: 800px 800px;
display: none;
}
</style>
效果分析:
1-点击小图片,添加被选中的样式,中图片和大图片切换
2-鼠标移入中图片,遮罩层显示;移出,遮罩层和大图片隐藏
3-鼠标在中盒子中移动,遮罩层跟随移动
4-遮罩层移动,大盒子图片跟随移动
代码实现:
// 创建放大镜Enlarge构造函数
function Enlarge(){
// 获取要操作的元素,并放到实例对象的属性中
this.box = document.querySelector('.box')
this.middleBox = document.querySelector('.middleBox')
this.middleImg = document.querySelector('.middleBox>img')
this.shade = document.querySelector('.shade')
this.bigBox = document.querySelector('.bigBox')
this.smallImgs = document.querySelectorAll('.smallBox>img')
}
// 给原型添加一个bind方法,实现元素的事件绑定
Enlarge.prototype.bind = function(){
// 给每一张小图片绑定点击事件
for(let i = 0; i<this.smallImgs.length; i++){
this.smallImgs[i].onclick = () => {
// 1-实现小图样式切换
this.tab(this.smallImgs[i])
}
}
// 中图片中鼠标移入移出事件
this.middleBox.onmouseenter = ()=>{
this.shade.style.display = 'block'
this.bigBox.style.display = 'block'
// 鼠标移动事件
this.middleBox.onmousemove = ()=> {
// 遮罩层跟随鼠标一起移动
this.move()
}
}
this.middleBox.onmouseleave = () => {
this.shade.style.display = 'none'
this.bigBox.style.display = 'none'
this.middleBox.onmousemove = null
}
}
// 给原型添加一个tab方法,实现切换小图样式和中大图片
Enlarge.prototype.tab = function(ele){
for(let i=0; i<this.smallImgs.length; i++){
this.smallImgs[i].className = ''
}
ele.className = 'active'
// 切换中盒子和大盒子中的图片
let bigImg = ele.getAttribute('bigImg')
let middleImg = ele.getAttribute('middleImg')
this.middleImg.setAttribute('src',middleImg)
this.bigBox.style.backgroundImage = `url(${bigImg})`
}
// 给原型添加一个move方法 ,遮罩层跟随鼠标一起移动
Enlarge.prototype.move = function(e){
e = e || window.event
// 获取鼠标相对于页面左上角的位置
let x = e.pageX
let y = e.pageY
// 获取遮罩层的一般宽高
let shadeHalfWidth = this.shade.clientWidth/2
let shadeHalfHeight = this.shade.clientHeight/2
// 获取中图片盒子距离页面上方和左方的位置
let boxLeft = this.box.offsetLeft
let boxTop =this.box.offsetTop
// 判断鼠标在盒子中移动的范围
if(x<shadeHalfWidth+boxLeft){
x = shadeHalfWidth+boxLeft
}
if(y<shadeHalfHeight+boxTop){
y = shadeHalfHeight+boxTop
}
if(x>boxLeft+this.middleBox.clientWidth-shadeHalfWidth){
x = boxLeft+this.middleBox.clientWidth-shadeHalfWidth
}
if(y>boxTop+this.middleBox.clientHeight-shadeHalfHeight){
y = boxTop+this.middleBox.clientHeight-shadeHalfHeight
}
// 将计算好的坐标赋值给遮罩层
this.shade.style.left = x - boxLeft - shadeHalfWidth + 'px'
this.shade.style.top = y - boxTop - shadeHalfHeight + 'px'
// 遮罩层移动,大图片跟随移动
this.bigImgMove()
}
// 在原型中添加一个bigImgMove函数,实现大图片移动
Enlarge.prototype.bigImgMove = function(){
// 获取遮罩层在中盒子中的位置
let shadeX = parseInt(getStyle(this.shade,'left'))
let shadeY = parseInt(getStyle(this.shade,'top'))
let bigImgSize = getStyle(this.bigBox,'background-size')
let bigImgWidth = parseInt(bigImgSize.split(' ')[0])
let bigImgHeight = parseInt(bigImgSize.split(' ')[1])
// 获取垂直和水平百分比
let xPercent = shadeX / this.middleBox.clientWidth
let yPercent = shadeY / this.middleBox.clientHeight
// 根据百分比计算大和中背景图移动的距离
let bigImgLet = bigImgWidth * xPercent
let bigImgTop = bigImgHeight * yPercent
// 位置赋值给大盒子
this.bigBox.style.backgroundPosition = `-${bigImgLet}px -${bigImgTop}px`
}
// 实例化
let enlarge = new Enlarge()
enlarge.bind()
// 获取元素样式
function getStyle(ele,style){
try{
return window.getComputedStyle(ele)[style]
}catch(error){
return ele.currentStyle[style]
}
}