本文分享一个电商平台常见查看商品细节图案例,如某东网站手机类别中具体某一部手机详情页中,手机的细节图展示,左侧小图获得用户鼠标焦点即可在屏幕右侧展示出该图片区域的大图效果,其中JS部分主要涉及鼠标经过、鼠标离开、鼠标移动等事件以及含有一个小算法公式,先展示效果:
某电商平台效果图展示:
本案例代码部分:HTML结构:
<div class="box">
<img src="images/s3.png" alt="">
<div class="mask"></div>
<div class="big">
<img src="images/big.jpg" alt="">
</div>
</div>
CSS样式:
<style>
* {
padding: 0;
margin: 0;
}
.box {
position: relative;
top: 70px;
left: 30px;
width: 400px;
height: 400px;
border: 1px solid #ccc;
}
.box > img {
height: 100%;
}
.mask {
display: none;
position: absolute;
top: 0;
left: 0;
width: 300px;
height: 300px;
box-sizing: border-box;
background-color: rgba(254, 222, 79, .5);
border: 1px solid #ccc;
cursor: move;
/*让鼠标的状态改成十字型*/
}
.big {
display: none;
position: absolute;
top: 0;
left: 410px;
width: 500px;
height: 500px;
border: 1px solid #ccc;
overflow: hidden;
z-index: 999;
}
.big img {
/* 一定要给.big下的img定位属性它的位置才能随着遮罩层的移动而移动哦 */
position: absolute;
top: 0;
left: 0;
}
</style>
JavaScript行为:
<script>
window.addEventListener('load', function () {
// 1.获取元素
var box = document.querySelector('.box');
var mask = document.querySelector('.mask');
var big = document.querySelector('.big');
// 2.注册事件
// (1)box鼠标经过即显示出遮罩层mask和右侧大图 onmouseover
box.addEventListener('mouseover', function () {
mask.style.display = 'block';
big.style.display = 'block';
})
// (2)box鼠标离开即隐藏遮罩层mask和右侧大图 onmouseout
box.addEventListener('mouseout', function () {
mask.style.display = 'none';
big.style.display = 'none';
})
// (3)让mask遮罩层随着鼠标移动(此事件要写在获得鼠标的情况下)
box.addEventListener('mousemove', function (e) {
// (1). 先计算出鼠标在盒子内的坐标,鼠标在盒子里的坐标=鼠标在屏幕中的坐标-盒子的offsetLeft/offsetTop
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
// (2) 鼠标在遮罩层中应该处于中心的位置,所以还要把鼠标从遮罩层的左上角往右往下移动遮罩层宽高的一半才行,即鼠标在盒子里的坐标减去盒子高度的一半和宽度的一半就是我们mask 的最终 left 和top值了
var maskX = x - mask.offsetWidth / 2; // 鼠标位置在遮罩层水平中间
var maskY = y - mask.offsetHeight / 2; // 鼠标位置在遮罩层垂直中间
// (3) 我们mask 遮罩层水平移动的距离即maskX= 遮罩层的父盒子的宽-遮罩层的宽,而遮罩层垂直移动的距离即maskY= 遮罩层的父盒子的高-遮罩层的高
// (4) 如果x 坐标小于了0 就让他停在0 的位置
// 遮挡层的最大移动距离= 遮罩层的父盒子的宽-遮罩层的宽(因为此案例的遮罩层是一个正方形,所以水平和垂直的范围是一致的)
var maskMax = box.offsetWidth - mask.offsetWidth; // 遮罩层的最大移动距离
// 判断限定遮罩层的可移动范围:水平可移动范围:
maskX <= 0 ? maskX = 0 : maskX = maskX; // 水平最小可移动范围
maskX >= maskMax ? maskX = maskMax : maskX = maskX; // 水平最小大可移动范围
// 判断限定遮罩层的可移动范围:垂直可移动范围:
maskY <= 0 ? maskY = 0 : maskY = maskY; // 垂直最小可移动范围
maskY >= maskMax ? maskY = maskMax : maskY = maskY; // 垂直最大可移动范围
// 将鼠标的坐标值给mask的left和top(mask是有定位的)注意要加px单位!!!
mask.style.left = maskX + 'px';
mask.style.top = maskY + 'px';
// (5)让右侧大图随着遮罩层移动而移动
// 大图片的移动距离 = 遮挡层移动距离 * 大图片最大移动距离 / 遮挡层的最大移动距离
// 获取大图
var bigImg = big.querySelector('img');
// 大图片最大移动距离
var bigMax = bigImg.offsetWidth - big.offsetWidth;
// 大图片的移动距离 X Y
var bigX = maskX * bigMax / maskMax;
var bigY = maskY * bigMax / maskMax;
// 注意:1.bigImg获取到的元素需要有CSS定位属性才能移动位置的,没有定位位置是不会变的哦
// 2.大图的移动和遮罩层移动的方向是相反的哦,因为遮罩层往左移动时实际上大图是要往右移动的,所以值是负数
bigImg.style.left = -bigX + 'px';
bigImg.style.top = -bigY + 'px';
})
})
</script>
效果展示:
1.程序运行,用户鼠标还未经过左侧小图(.box)时:
2.鼠标经过左侧小图时 :
3.鼠标在左侧小图(.box)上移动时:
案例知识点及细节:1.HTML结构部分:主要结构是一个大的div装一张图片(即左侧小图)和两个div(一个遮罩层、一个右侧装大图的div),这三个元素,默认显示的只有左侧的小图,另外的遮罩层和大图都是默认隐藏的(即display: none;),且遮罩层和大图都是通过定位(子绝父相)放到对应的位置上的,这里需要注意的是右侧大图的z-index需要给个值,因为一般右侧大图原本的区域是有内容显示的,大图可能会被压在下面,所以要提一下层级;
2.CSS样式部分:样式就根据一般样式给就可以,唯一一点需要注意的是大图里面的img要给一个position: absolute;的绝对定位,这样JS部分才能通过left和top来移动图片的位置实现大图随小图内鼠标的移动而移动的效果;
3.JavaScript部分:主要设计鼠标经过事件(onmouseover)、鼠标离开事件(onmouseout)和鼠标移动事件(onmousemove),注意写在addEventListener()内则不需要加on,且需要用引号引起来,主要思路是给最外层的大盒子(即.box)添加鼠标经过事件,鼠标经过则让遮罩层和右侧大图显示出来(即display: block;),鼠标离开则隐藏(即display: none;),然后再给.box添加鼠标移动事件,鼠标在其内部移动先获取到鼠标的坐标(用鼠标的e.pageX - box.offsetLeft得X坐标;Y坐标同理可得),得到鼠标的坐标就可以决定遮罩层的位置了,但是注意鼠标的坐标来决定遮罩层的位置时鼠标应该是在遮罩层的中心位置,所以要把得到的鼠标坐标往下和往右移动遮罩层高宽的一半,这样得到的坐标值赋值到遮罩层上(决定的是遮罩层的左上角坐标)才对;
4.遮罩层可以随着鼠标移动而移动了,但是还有一点那就是遮罩层的移动范围应该是受限的,它不能超出父盒子,所以要添加一个判断,如果遮罩层往左走到了0则不能再走,而往右走可以走多少其实本身是右遮罩层和其父盒子(即.box)的宽度来决定的,因为遮罩层的移动范围是从0~(box.offsetWidth - mask.offsetWidth),即0到父盒子的宽度减去遮罩层的宽度得来的;
5.遮罩层可以正常移动了范围也限制好了接下来就是右侧大图的显示了,这里主要设计到一个算法即:
因为大图的移动和遮罩层的移动其实是有比例关系的,即遮罩层移动多少大图按照该比例就移动多少(比如遮罩层移动1px,大图移动2px,那么遮罩层移动2px时大图就应该移动4px),由此公式可得出小图移动时大图对应应该移动的距离数据,然后将此数据赋值给右侧大图(即div下的img),通过style.left和style.top即可改变图标的位置(主要值要加px单位),但是注意,大图的移动和遮罩层的移动其实是相反的哦,如遮罩层往右移动,其实大图是往左移的(因为大图要往左走才能展示其右侧区域),所以给left和top赋的值要加个负号哦。
如此,便基本介绍了本案例所涉及的基本知识点和注意点,建议可以结合代码(内含详细注释)可以更清晰的看到编程步骤以及实现思路。本案例是纯JS底层代码实现(所以具有很多可以优化的地方)或许会有更好更简单的方法实现此功能,但是使用最基本的JS代码实现可以比较清晰的理解核心代码和算法。