本文介绍一下电商网站用的比较多的案例,放大镜案例,先来看看效果吧.
需求分析:
当鼠标移入进小盒子的时候即左边的盒子,显示出遮罩层还有大盒子,大盒子会出现遮罩层遮挡的部分,达成一个放大的效果
当鼠标在小盒子里移动时,大盒子里显示的图片对应的会跟着改变.
那我们该如何实现这个效果呢?
其实呢,这个案例就是对js事件,还有一些offset家族还有事件对象的三大坐标系(screen,client,page)的应用.
了解过这些知识的,会很容易理解本文的代码,那么我将带来原生JS还有jQuery的实现方式,两者实现方式都差不多,
仅供参考...下面给出代码然后在下面分析.
页面代码:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
* {
margin: 0;
padding: 0;
}
.box {
width: 350px;
height: 350px;
margin: 100px;
border: 1px solid #ccc;
position: relative;
}
.big {
width: 400px;
height: 400px;
position: absolute;
top: 0;
left: 360px;
border: 1px solid #ccc;
overflow: hidden;
display: none;
}
.mask {
width: 175px;
height: 175px;
background: rgba(255, 255, 0, 0.4);
position: absolute;
top: 0;
left: 0;
cursor: move;
display: none;
}
.small {
position: relative;
}
.box img {
vertical-align: top;
}
#bigBox > img {
/*是让里面的图片脱标,为的就是让里面的图片进行一个移动*/
position: absolute;
}
</style>
</head>
<body>
<div class="box" id="box">
<div class="small" id="smallBox">
<img src="images/001.jpg" width="350" alt=""/>
<div class="mask" id="mask"></div>
</div>
<div class="big" id="bigBox">
<img id="bigImg" src="images/0001.jpg" width="800" alt=""/>
</div>
</div>
</body>
原生js代码:
var box = document.getElementById('box');
var smallBox = document.getElementById('smallBox');
var mask = document.getElementById('mask');
var bigBox = document.getElementById('bigBox');
var bigImg = document.getElementById('bigImg');
//注册事件
box.onmouseover = function () {
mask.style.display = 'block';
bigBox.style.display = 'block';
}
box.onmouseout = function () {
mask.style.display = 'none';
bigBox.style.display = 'none';
}
smallBox.onmousemove = function (e) {
//需要获取到x,y
e = e || window.event;
var x = getPagePoint(e).pageX - box.offsetLeft;
var y = getPagePoint(e).pageY - box.offsetTop;
x -= mask.offsetWidth/2;
y -= mask.offsetHeight/2;
//边界检测
x = x<0?0:x;
x = x>175?175:x;
y = y<0?0:y;
y = y>175?175:y;
//赋值
mask.style.left = x + 'px';
mask.style.top = y + 'px';
//大图片移动
bigImg.style.left = -x*(bigBox.offsetWidth/mask.offsetWidth) + 'px';
bigImg.style.top = -y*(bigBox.offsetHeight/mask.offsetHeight) + 'px';
}
/** 11.获取事件的pageX和pageY :事件触发点相对于页面左上角距离
* @param e:事件对象
* @return 对象类型 pageX:左边距离 pageY:上边距离
*/
function getPagePoint ( e ) {
e = e || window.event;//事件对象兼容
return {
pageX : e.pageX || getScroll().scrollLeft + e.clientX,
pageY : e.pageY || getScroll().scrollTop + e.clientY,
}
}
首先,我们先获得我们需要操作的元素,整一个盒子(装着大盒子和小盒子),大盒子,小盒子,大图片,遮罩层.
给我们整一个盒子注册一个移入事件和移出事件,控制遮罩层和大盒子的显示与隐藏
紧接着我们小盒子注册一个移动事件.
我们用一个封装好的函数(仅用于处理兼容性)来获取鼠标距离document的距离,接着用这个值减去整个盒子距离
document的坐标,这样就可以获取到鼠标距离我这个小盒子左上角的x,y坐标.
因为最后我们要将x,y赋予遮罩层的left和top值
要让我们这个鼠标坐标在遮罩层居中,那么我们需要用刚获取的x,y坐标减去遮罩层一半的宽度和一半的高度.
这样我们就可以发现鼠标一直在遮罩层的中心了,那么这时会出现一个问题,就是遮罩层会出界,那么,为了让他不出界
我们需要做一个简单的边界检测了,如果我们的遮罩层left超过了小盒子的宽度的一半或者left小于0
那么就会出现出界的情况,所以我们只要做个判断,在他出界的时候做好处理即可.
最后一波,因为遮罩层移动的时候,大盒子的图片会跟着移动,那么我们很容易就想到,我们只需要在移动遮罩层的时候,
让大盒子里的大图片跟着移动就可以了,记得算好大盒子与遮罩层的倍数.
下面给出jQuery的代码
<script src="jquery-1.12.4.js"></script>
<script>
$(function () {
//入口函数
var box = $("#box");
var smallBox = $('#smallBox');
var mask = $('#mask');
var bigBox = $('#bigBox');
var bigImg = $('#bigImg');
box.on('mouseenter', function () {
mask.show();
bigBox.show();
})
box.on('mouseleave', function () {
mask.hide();
bigBox.hide();
})
smallBox.on('mousemove', function (e) {
var x = e.pageX - box.offset().left;
var y = e.pageY - box.offset().top;
x -= mask.outerWidth()/2;
y -= mask.outerHeight()/2;
console.log(x);
console.log(y);
//边界检测
x = x<0?0:x;
x = x>175?175:x;
y = y<0?0:y;
y = y>175?175:y;
//赋值
mask.css({
left: x + 'px',
top: y + 'px'
})
bigImg.css({
left: -x*(bigBox.outerWidth()/mask.outerWidth()) + 'px',
top: -y*(bigBox.outerHeight()/mask.outerHeight()) + 'px'
})
})
})
</script>
这里可以使一下jQuery的position属性,可以更方便的获取到遮罩层距离小盒子的定位距离,这里就不过多赘述了.