案例:商品放大镜效果

整个案例可以分为三个功能模块:

① 鼠标经过小图片盒子,黄色的遮挡层和大图片盒子显示,离开则隐藏遮挡层和大图片的盒子的功能:就是显示与隐藏。

② 黄色的遮藏层要跟随鼠标移动的功能:

  • 把鼠标坐标给遮挡层不合适,因为遮挡层是用定位方式设置的,所以它的坐标是以父盒子为准的
  • 首先获得鼠标在盒子里的坐标
  • 之后把数值给遮挡层作为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';
    });
});
原文地址:https://www.cnblogs.com/zcy9838/p/12953803.html