小兔鲜儿网页案例进阶版1--实现商品放大镜效果
前面有一章节介绍了使用html+css实现小兔鲜儿网页案例,但是这是一个纯静态网页。最近因为又补充学习了一下前端基础知识WebAPI篇,看到了老师实现的放大镜效果和固定侧边栏效果,因此,突发奇想,直接在小兔鲜儿案例上实现了上述两种功能。
首先,先看下商品详情页面的放大镜效果是什么样子的。由于手上没有太多图片,所以两侧图片只是设置了不同尺寸来展现放大镜效果。图像放大镜的原理是鼠标经过左侧小图片盒子,出现黄色遮盖,然后右侧大图片展示。鼠标移出左侧区域,两个显示出来的区域被隐藏。黄色遮盖会随着鼠标的移动而移动,并且大图片也跟随移动。
图一、商品放大镜效果
前面的使用html+css初步完成小兔鲜儿案例中中给出了静态页面的代码,这里在此基础上写了个简单的商品详情页展示放大镜效果。首先看下新增放大镜效果后项目结构是什么样子的。上面标注颜色的地方为新增详情页放大镜效果的代码。其中animate.js为侧边栏效果代码,下一个博客将进行介绍。
首先在index.html的商品列表展示模块的一个吸尘器图片a标签处添加了跳转页面到详情页功能,代码如下所示:
<a href="./details.html"> <img src="./uploads/new_goods_1.jpg" alt=""> <h3>无线吸尘器</h3> <p><span>¥</span> 899</p> </a>
商品详情页detail.html如下所示
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>商品放大镜效果</title> 8 <script src="./js/detail.js"></script> 9 <style> 10 * { 11 margin: 0; 12 padding: 0; 13 } 14 body { 15 background-color: #fff; 16 font: 12px/1.5 'Microsoft YaHei', 'Heiti SC', tahoma, arial, 'Hiragino Sans GB', \\5B8B\4F53, sans-serif; 17 color: #666 18 } 19 /*清除浮动*/ 20 .clearfix:after { 21 visibility: hidden; 22 clear: both; 23 display: block; 24 content: "."; 25 height: 0 26 } 27 .clearfix { 28 *zoom: 1 29 } 30 .w { 31 width: 1200px; 32 margin: 0 auto; 33 } 34 .detail-container { 35 margin-top: 20px; 36 margin-left: 20px; 37 } 38 .preview_wrap { 39 width: 400px; 40 height: 590px; 41 } 42 .fl { 43 float: left; 44 } 45 .show_img { 46 position: relative; 47 height: 398px; 48 border: 1px solid #ccc; 49 } 50 img { 51 display: block; 52 width: 50%; 53 border: 0; 54 /* vertical-align: middle; */ 55 margin: 100px auto; 56 } 57 .mask { 58 display: none; 59 position: absolute; 60 top: 0; 61 left: 0; 62 width: 260px; 63 height: 260px; 64 background-color: #efde4f; 65 opacity: 0.5; 66 cursor: move; 67 } 68 .zoom_big { 69 display: none; 70 position: absolute; 71 left: 410px; 72 top: 0; 73 width: 500px; 74 height: 500px; 75 /* background-color: pink; */ 76 z-index: 999; 77 border: 1px solid #ccc; 78 overflow: hidden; 79 } 80 .zoom_big img { 81 position: absolute; 82 top: 0; 83 left: 0; 84 width: 90%; 85 margin: 10px; 86 } 87 .itemInfo_wrap { 88 width: 518px; 89 } 90 .fr { 91 float: right; 92 } 93 </style> 94 </head> 95 <body> 96 <div class="detail-container w"> 97 <!-- 展示列表 --> 98 <span>商品详情 ></span> 吸尘器 99 <div class="product_intro clearfix"> 100 <!-- 预览区域 --> 101 <div class="preview_wrap fl"> 102 <div class="show_img"> 103 <img src="./uploads/new_goods_1.jpg" alt=""> 104 <!-- 遮盖层 --> 105 <div class="mask"></div> 106 <div class="zoom_big"> 107 <img src="./uploads/new_goods_1.jpg" alt="" class="zoomBigImg"> 108 </div> 109 </div> 110 </div> 111 <!-- 产品详情区域 --> 112 <div class="itemInfo_wrap fr"> 113 哈哈哈哈或或或或,这边没有详情 114 </div> 115 </div> 116 </div> 117 </body> 118 </html>
下面是detail.js代码
1 window.addEventListener('load', zoom); 2 function zoom () { 3 let show_img = document.querySelector('.show_img'); 4 let mask = document.querySelector('.mask'); 5 let zoom_big = document.querySelector('.zoom_big'); 6 // 1、当鼠标经过show_img就显示mask遮挡层和zoom_big大盒子 7 show_img.addEventListener('mouseover', function() { 8 mask.style.display = 'block'; 9 zoom_big.style.display = 'block'; 10 }) 11 // 2、当鼠标离开show_img就隐藏mask遮挡层和zoom_big大盒子 12 show_img.addEventListener('mouseout', function() { 13 mask.style.display = 'none'; 14 zoom_big.style.display = 'none'; 15 }); 16 17 show_img.addEventListener('mousemove', function(e) { 18 // 1、先计算鼠标在盒子内的坐标 19 let xPosition = e.pageX - this.offsetLeft; // 鼠标据页面的距离 - 盒子左侧的距离(需要看有没有定位) = 鼠标在盒子内的距离 20 let yPosition = e.pageY - this.offsetTop; 21 // console.log(this.offsetLeft); 22 // 2、减去盒子高度的一半,就是mask的left和top了 23 // 3、mask移动的距离赋值 24 let maskX = xPosition - mask.offsetWidth / 2; 25 let maskY = yPosition - mask.offsetHeight / 2; 26 // 遮挡层最大移动距离 (因为盒子和遮挡层都是正方形,所以宽高最大距离相同)-- 就是鼠标移动区域盒子(show_img的宽高)-遮盖层的宽高 27 let maskMaxDist = this.offsetHeight - mask.offsetHeight; 28 //4、如果x坐标小于0 ,就让他停在0的位置 29 if (maskX < 0) { 30 maskX = 0; 31 } else if (maskX >= maskMaxDist) { // mask盒子 left最大距离左侧的距离是盒子的宽度-mask的宽度 32 maskX = maskMaxDist; 33 } 34 if (maskY < 0) { 35 maskY = 0; 36 } else if (maskY >= maskMaxDist) { // mask盒子 left最大距离左侧的距离是盒子的宽度-mask的宽度 37 maskY = maskMaxDist 38 } 39 mask.style.left = maskX + 'px'; // 将mask中间点位于鼠标位置,则mask的left和top - mask的宽高 40 mask.style.top = maskY + 'px'; 41 // 放大镜的大图片移动距离 = (遮挡层移动距离(maskX和maskY) * 放大镜大图片最大移动距离)/ 遮挡层最大移动距离(就是移动后,遮挡层不能超过盒子的范围,遮挡层left/top的距离) 42 let zoomBigImg = document.querySelector('.zoomBigImg'); 43 // 放大镜大图片最大移动距离 44 let zoomBigMaxDist = zoomBigImg.offsetWidth - zoom_big.offsetWidth; 45 // 放大镜的大图片移动距离 46 let zoom_bigX = maskX * zoomBigMaxDist / maskMaxDist; 47 let zoom_bigY = maskY * zoomBigMaxDist / maskMaxDist; 48 zoomBigImg.style.left = zoom_bigX + 'px'; 49 zoomBigImg.style.top = zoom_bigY + 'px'; 51 }); 52 }
这里记录一个小知识点,加深下自己的记忆力
1、mouseover 经过自身盒子和子盒子都会触发鼠标事件
2、mouseenter只会经过自身盒子触发,和mouseleave搭配
3、window.addEvevtListener('load', function(){}),是在页面文档完全加载完毕后执行里面的函数。
好了,到这里商品详情页放大镜效果就实现了。
这个案例并不是太完美,一些样式设置并不完全,放大镜效果也不是等比例放大,后续会进行改善,先记录下来,防止忘记😃。