案例:商品放大镜效果
整个案例可以分为三个功能模块:
① 鼠标经过小图片盒子,黄色的遮挡层和大图片盒子显示,离开则隐藏遮挡层和大图片的盒子的功能:就是显示与隐藏。
② 黄色的遮藏层要跟随鼠标移动的功能:
- 把鼠标坐标给遮挡层不合适,因为遮挡层是用定位方式设置的,所以它的坐标是以父盒子为准的
- 首先获得鼠标在盒子里的坐标
- 之后把数值给遮挡层作为left和top值
- 此时用到鼠标移动事件,但是还是在小图片盒子内移动
- 鼠标位置应该在遮挡层的正中间,因此遮挡层需要再减去盒子自身高度和宽度的一半
- 遮挡层不能超出小盒子的范围(要把遮挡层卡在小图片的盒子内)
- 如果小于0,就把遮挡层的坐标设置为0
- 如果大于遮挡层最大的移动距离,就把坐标设置为最大的移动距离
- 遮挡层的最大移动距离:小图片盒子宽度减去遮挡层盒子宽度
③ 移动黄色的遮挡层,同时大图片也要跟随移动的功能:
大图片的移动距离公式为:
注意:大图片与遮挡层移动的方向应该是相反的!!!自己好好想一想是不是这个理
<!-- 页面布局 --> <div class="preview_img"> <img src="upload/s3.png" alt=""> <div class="mask"></div> <div class="big"> <img src="upload/big.jpg" alt="" class="bigImage"> </div> </div>
/* css样式 */ .preview_img { position: relative; height: 398px; border: 1px solid #ccc; } .mask { display: none; position: absolute; top: 0; left: 0; width: 300px; height: 300px; background-color: #fede4f; /* 设置背景颜色的透明度 */ opacity: .5; border: 1px solid #ccc; /* 鼠标经过时显示为move的形状 */ cursor: move; } .big { display: none; /* 使用绝对定位定到预览图盒子的右边 */ position: absolute; left: 410px; top: 0; /* 提高层级,使该放大图显示在最上层 */ z-index: 999; width: 500px; height: 500px; background-color: pink; border: 1px solid #ccc; /* 里面的图片太大会溢出盒子,做溢出隐藏处理 */ overflow: hidden; } .big img { position: absolute; top: 0; left: 0; }
// JS逻辑代码 window.addEventListener('load', function() { // 获取元素 var preview_img = document.querySelector('.preview_img'); var mask = document.querySelector('.mask'); var big = document.querySelector('.big'); // 1. 当我们鼠标经过preview_img就显示和隐藏mask遮挡层和big大盒子 preview_img.addEventListener('mouseover', function() { mask.style.display = 'block'; big.style.display = 'block'; }); preview_img.addEventListener('mouseout', function() { mask.style.display = 'none'; big.style.display = 'none'; }); // 2. 鼠标移动的时候,让遮盖层的盒子跟着鼠标来走 preview_img.addEventListener('mousemove', function(e) { //(1)先计算出鼠标在盒子内的坐标 var x = e.pageX - this.offsetLeft; var y = e.pageY - this.offsetTop; // console.log(x, y); // 修改坐标只能用style,offset是只读的 //(2)让鼠标始终在遮盖层的正中间显示:减去盒子高度和宽度的一半 //(3)mask移动的距离 var maskX = x - mask.offsetWidth / 2; var maskY = y - mask.offsetHeight / 2; // 遮挡层的最大移动距离:因为遮挡层mask和图片preview_img都是正方形的, // 所以preview_img.offsetWidth - mask.offsetWidth和preview_img.offsetHeight - mask.offsetHeight是一样的 var maskMax = preview_img.offsetWidth - mask.offsetWidth; //(4)使遮挡层mask不超出preview_img的范围 if (maskX <= 0) { maskX = 0; }else if(maskX >= maskMax) { maskX = maskMax; } if (maskY <= 0) { maskY = 0; }else if(maskY >= maskMax) { maskY = maskMax; } mask.style.left = maskX + 'px'; mask.style.top = maskY + 'px'; // 3. 大图片的移动距离 = 遮挡层移动距离 * 大图片最大移动距离 / 遮挡层的最大移动距离 // 大图 var bigImage = document.querySelector('.bigImage'); // 大图片最大移动距离(大图片的大小比它的父盒子要大很多) var bigMax = bigImage.offsetWidth - big.offsetWidth; // 大图片的移动距离 X Y var bigX = maskX * bigMax / maskMax; var bigY = maskY * bigMax / maskMax; // 注意,大图片必须与父盒子是定位的关系才能移动 // 注意:大图片与遮挡层移动的方向应该是相反的 bigImage.style.left = -bigX + 'px'; bigImage.style.top = -bigY + 'px'; }); });