文章目录
案例描述
在浏览器的左边有一张大图,下面有两张小图,点击任何一张小图会在大图的位置显示这张小图的画面。进入大图,鼠标所指之处有一个透明的黄色区域,而在大图的右边(以下称超大图)会放大这一区域
案例图示
HTML
<body>
<div id="box">
<div id="small">
<img src="./program1/images/1.jpg" >
<span id="mask"></span>
</div>
<div id="big">
<img src="./program1/images/1.jpg" >
</div>
</div>
<div id="list">
<ul>
<li><img src="./program1/images/1.jpg" width="100px"></li>
<li><img src="./program1/images/2.jpg" width="100px"></li>
</ul>
</div>
</body>
CSS样式
详解请看注释
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
list-style: none;
border: none;
}
#box {
width: 250px;
height: 160px;
margin-left: 100px;
margin-top: 100px;
position: relative;
}
#small {
width: 100%;
height: 100%;
border: 1px solid #ccc;
/* 放大镜操作 */
position: relative;
}
#small img{
width: 100%;
height: 100%;
padding: 2px;
}
/* 显微镜 */
#mask {
width: 50px;
height: 50px;
/* 透明图 */
background-color:rgba(255, 255, 0,.4);
position: absolute;
left: 0;
top: 0;
cursor: move;
/* 隐藏 */
display: none;
}
#big {
width: 400px;
height: 255px;
border: 1px solid #ccc;
/* 为以后大图位置改变作准备 */
position: absolute;
/* 250 + 10 margin */
left: 260px;
top: 0;
/* 图片超出部分隐藏 */
overflow: hidden;
/* 整个大图开始是隐藏的 */
display: none;
}
#big img {
width: 700px;
padding: 2px;
position: absolute;
left: 0;
top: 0;
margin: 0 auto;
background-color: red;
}
#list {
margin-top: 5px;
margin-left: 100px;
}
#list li {
float: left;
margin-right: 5px;
cursor: pointer;
}
</style>
JS代码
JS分解代码----小图点击事件
(1)首先设置一个value属性用于改变small_img中的图片src,value的值为其下标+1
(2)监听li中的点击事件时,要改变small_img(大图)中的图片展示和big_img(超大图)中的图片展示
for (let i = 0; i < allLi.length; i++) {
var li = allLi[i];
//设置一个value属性用于改变small_img中的图片src
li.setAttribute('value',i+1);
//监听li中的点击事件
li.addEventListener('click',function(){
//改变small_img中的图片展示
small_img.setAttribute('src',"./program1/images/" + this.getAttribute('value') +".jpg");
//改变big_img中的图片展示
big_img.setAttribute('src',"./program1/images/" + this.getAttribute('value') +".jpg");
});
}
JS分解代码----鼠标进入和移出
鼠标进入和移出都要改变放大镜和超大图的display属性。
进入时display属性值为*“block”*
移出时display属性值为*“none”*
//监听鼠标进入box
box.addEventListener('mouseover',function() {
//放大镜显示
mask.style.display = 'block';
//big图片显示
big.style.display = 'block';
});
//监听鼠标移出box
box.addEventListener('mouseout',function(){
//放大镜隐藏
mask.style.display = 'none';
//big图片隐藏
big.style.display = 'none';
})
});
JS分解代码----鼠标的移动
在鼠标进入事件中监听鼠标的移动
这里运用到事件对象和offset家族的知识
可以参考:
事件对象
offset家族
注意事项看注释
//监听鼠标的移动
small.addEventListener('mousemove',function(event){
//事件对象
var e = event || window.event;
//获取鼠标的位置 鼠标显示在mask中间:减去自身宽高度的一半
//最好用pageX、pageY,不要用clientX、clientY 防止有分页时出错
var small_x = event.pageX - box.offsetLeft - mask.offsetWidth*0.5;
var small_y= event.pageY - box.offsetTop - mask.offsetHeight*0.5;
JS分解代码----碰撞事件,放大镜的移动
写完上述代码,你会发现放大镜也能去到大图以外的区域,这不是我们所期望的,这里就需要用到碰撞事件了
这里还是用到了offset家族的知识
这里用到的思维是用if判断条件限制上下左右的边界
放大镜的移动就是改变它的top和left值(因为它相对父元素绝对定位)
不理解offset,请参考:offset家族
注意事项看注释
//放大镜碰撞
//相对于box 因为box有定位
if(small_x <= 0)
small_x = 0;
else if( small_x >= box.offsetWidth-mask.offsetWidth)
small_x = box.offsetWidth-mask.offsetWidth - 2; //除去边框
if(small_y <= 0)
small_y = 0;
else if( small_y >= box.offsetHeight-mask.offsetHeight)
small_y = box.offsetHeight-mask.offsetHeight - 2;
//放大镜跟着鼠标的位置
mask.style.left = small_x + 'px';
mask.style.top = small_y + 'px';
JS分解代码----超大图的位置改变
big_img.style.left 和 big_img.style.top为负值(你可以试试去掉负号是什么样的效果)
这里的重点是这个公式
//big_img中的位置相应改变
//公式:small_x/big_x = small_width/big_img_width
big_img.style.left = - (event.pageX - box.offsetLeft) /(small.offsetWidth / big.offsetWidth) + 'px';
big_img.style.top = -( event.pageY - box.offsetTop)/( small.offsetHeight / big.offsetHeight) + 'px';
JS全部代码展示
<script>
window.addEventListener ('load',function(){
//获取元素
var small = $('small');
var big = $('big');
var mask = $('mask');
var allLi = document.getElementsByTagName('li');
var small_img = small.children[0];
var big_img = big.children[0];
//遍历每一个li中的点击事件
for (let i = 0; i < allLi.length; i++) {
var li = allLi[i];
//设置一个value属性用于改变small_img中的图片src
li.setAttribute('value',i+1);
//监听li中的点击事件
li.addEventListener('click',function(){
//改变small_img中的图片展示
small_img.setAttribute('src',"./program1/images/" + this.getAttribute('value') +".jpg");
//改变big_img中的图片展示
big_img.setAttribute('src',"./program1/images/" + this.getAttribute('value') +".jpg");
});
}
//监听鼠标进入box
box.addEventListener('mouseover',function() {
//放大镜显示
mask.style.display = 'block';
//big图片显示
big.style.display = 'block';
//监听鼠标的移动
small.addEventListener('mousemove',function(event){
//事件对象
var e = event || window.event;
//获取鼠标的位置 鼠标显示在mask中间:减去自身宽高度的一半
//最好用pageX、pageY,不要用clientX、clientY 防止有分页时出错
var small_x = event.pageX - box.offsetLeft - mask.offsetWidth*0.5;
var small_y= event.pageY - box.offsetTop - mask.offsetHeight*0.5;
//放大镜碰撞
// console.log(mask.offsetLeft) ;
//相对于box 因为boxx有定位
if(small_x <= 0)
small_x = 0;
else if( small_x >= box.offsetWidth-mask.offsetWidth)
small_x = box.offsetWidth-mask.offsetWidth - 2; //除去边框
if(small_y <= 0)
small_y = 0;
else if( small_y >= box.offsetHeight-mask.offsetHeight)
small_y = box.offsetHeight-mask.offsetHeight - 2;
//放大镜跟着鼠标的位置
mask.style.left = small_x + 'px';
mask.style.top = small_y + 'px';
//big_img中的位置相应改变
//公式:small_x/big_x = small_width/big_img_width
big_img.style.left = - (event.pageX - box.offsetLeft) /(small.offsetWidth / big.offsetWidth) + 'px';
big_img.style.top = -( event.pageY - box.offsetTop)/( small.offsetHeight / big.offsetHeight) + 'px';
});
});
//监听鼠标移出box
box.addEventListener('mouseout',function(){
//放大镜隐藏
mask.style.display = 'none';
//big图片隐藏
big.style.display = 'none';
})
});
//封装
function $(id) {
return typeof id === 'string'? document.getElementById(id):null;
}
</script>