放大镜——功能实现
分析
-
事件 :
-
- 鼠标移入事件 : 显示 ( 焦点,大图)
-
- 鼠标移出事件 : 隐藏 ( 焦点,大图)
-
- 列表鼠标移入 : 切换图片;
-
-
初始化布局的时候,放大镜和焦点框的比例很重要;
-
目前定义为 1 : 0.6;
HTML代码
<div class="container">
<!-- 图片部分 -->
<div class="img">
<img src="./images/1.jpg" alt="">
<!-- 焦点框 -->
<div class="focus"></div>
</div>
<!-- 图片列表 -->
<div class="list">
<span class="active">
<img src="./images/1.small.jpg" alt="">
</span>
<span>
<img src="./images/2.small.jpg" alt="">
</span>
</div>
<!-- 大图部分 -->
<div class="big-img">
<img src="./images/1.big.jpg" alt="">
</div>
</div>
CSS代码
*{
margin: 0;
padding: 0;
}
.container{
width: 350px;
margin-left: 100px;
position: relative;
}
.img{
width: 350px;
height: 350px;
}
.img img{
width: 100%;
height: 100%;
}
.focus{
width: 238px;
height: 238px;
border: 1px solid #aaa;
background: 50% top no-repeat #fede4f;
opacity: .5;
cursor: move;
position: absolute;
left: 0;
top: 0;
z-index:9;
display: none;
}
.big-img{
width: 540px;
height: 540px;
position: absolute;
left: 350px;
top: 0;
overflow: hidden;
display: none;
}
.big-img img{
width: 800px;
height: 800px;
position: absolute;
}
.list span{
display: inline-block;
border: 2px solid #fff;
margin-left: 5px;
}
.list span.active{
border-color: #f10;
}
.list span:hover{
border-color: #f10;
}
.list {
padding-left: 20px;
padding-top: 20px;
}
JavaScript代码
class Magnifier{
constructor(){
this.img = document.querySelector(".img");
this.focus = document.querySelector(".focus");
this.big_img = document.querySelector(".big-img");
this.big_bg = document.querySelector(".big-img img");
this.scale = 0.6;
// - 为了获取元素的偏移距离,计算正确的focus位置;
this.container = document.querySelector(".container");
// 找到按钮元素;
this.btns = document.querySelectorAll(".list span");
// 图片数据;
this.img_list = [
{
small : "./images/1.jpg",
big : "./images/1.big.jpg"
},
{
small : "./images/2.jpg",
big : "./images/2.big.jpg"
}
]
this.init();
this.c_off = {
left : this.container.offsetLeft,
top : this.container.offsetTop,
}
// offset 家族是没办法测量 display 为none 的元素;
this.f_style = getComputedStyle( this.focus ),
this.i_style = getComputedStyle( this.img )
// 边界数据对象;
this.boundary = {
x : {
min : 0,
max : parseInt(this.i_style.width) - parseInt(this.f_style.width)
},
y : {
min : 0 ,
max : parseInt(this.i_style.height) - parseInt(this.f_style.height)
}
}
this.bindEvent();
}
init(){
this.focus.style.width = 350 * this.scale + "px";
this.focus.style.height = 350 * this.scale + "px";
this.big_img.style.width = 800 * this.scale + "px";
this.big_img.style.height = 800 * this.scale + "px";
}
bindEvent(){
this.img.addEventListener("mouseover" , ()=>{
this.show();
})
this.img.addEventListener("mouseout" , ()=>{
this.hide();
})
this.img.addEventListener("mousemove" , ( e ) => {
this.move(e.clientX , e.clientY);
})
for(let i = 0 ; i < this.btns.length ; i ++){
this.btns[i].addEventListener("mouseenter" , ()=>{
this.change( i );
})
}
}
show(){
this.focus.style.display = "block";
this.big_img.style.display = "block";
}
hide(){
this.focus.style.display = "none";
this.big_img.style.display = "none";
}
move( x , y ){
// 如果使用offset会出现 鼠标获取位置的参照物和focus元素定位的参照物不一致;
// - 导致元素位移位置不正确;
x = x - this.c_off.left - parseInt(this.f_style.width) / 2;
y = y - this.c_off.top - parseInt(this.f_style.height) / 2;
// 边界检测
x = x <= this.boundary.x.min ? this.boundary.x.min : x ;
x = x >= this.boundary.x.max ? this.boundary.x.max : x ;
y = y <= this.boundary.y.min ? this.boundary.y.min : y ;
y = y >= this.boundary.y.max ? this.boundary.y.max : y ;
this.focus.style.left = x + "px";
this.focus.style.top = y + "px";
this.big_bg.style.left = - x * ( 800 / 350 ) + "px";
this.big_bg.style.top = - y * ( 800 / 350 ) + "px";
}
change( index ){
this.btns.forEach( ele => ele.classList.remove("active") );
this.btns[index].classList.add("active");
this.img.children[0].src = this.img_list[index].small;
this.big_bg.src = this.img_list[index].big;
}
}
var m = new Magnifier;
点击链接下载资源:
资源包链接
原创不易,转载请注明出处。