原生js实现仿京东商品放大镜效果

一、执行效果

在这里插入图片描述

二、代码结构

1. HTML CSS

  1. class="preview"的div里面放小图片、黄色遮罩层和大图片
  2. 给黄色遮罩层和大图片position: absolute;,并定位至对应位置
  3. 大图片的div给固定宽高,图片超出部分overflow: hidden;
  4. cursor: move;给黄色遮罩层一个鼠标看起来可移动的样式

2. js

  • 获取对应元素,给.preview绑定鼠标移入和鼠标移出事件,分别对应显示遮罩层大图片与隐藏遮罩层大图片。

  • 再给.preview绑定鼠标移动事件,根据鼠标距离页面的x和y值,减去.preview距离页面的 offsetLeft 和 offsetTop 值算出鼠标在.preview内的相对位置。这时如果直接把结果给遮罩层的 left 和 top 的话,会导致遮罩层的左上角定点和鼠标重合,不太符合鼠标位于遮罩层中心的要求,所以给鼠标相对位置减去遮罩层的宽高的一半,达到鼠标位于遮罩层中间的效果。

  • 此时鼠标移动,遮罩层会超出.preview,此时根据下面公式计算可得:本题遮罩层最大可移动距离为400-300=100px,当遮罩层移动距离大于.preview的宽(高) - 遮罩层自己的宽(高)时,设置最大移动距离就等于.preview的宽(高) - 遮罩层自己的宽(高)最小可移动距离为0,所以限制当遮罩层移动位置小于0时,设置移动距离为0
    遮罩层的最大可移动距离 = . p r e v i e w 的宽(高) − 遮罩层自己的宽(高) 遮罩层的最大可移动距离 =.preview的宽(高) - 遮罩层自己的宽(高) 遮罩层的最大可移动距离=.preview的宽(高)遮罩层自己的宽(高)

  • 大图片最大可移动距离计算同理。

  • 最后根据易错点1所给公式对应出遮罩层移动距离和大图片移动距离的对照关系

三、易错点

  1. 根据比例来计算遮罩层的移动和大图片的移动对应关系,对应关系如下:

    • 大图片移动距离 / 大图片最大可移动距离 = 遮罩层移动的距离 / 遮罩层最大移动距离 大图片移动距离/大图片最大可移动距离 = 遮罩层移动的距离 / 遮罩层最大移动距离 大图片移动距离/大图片最大可移动距离=遮罩层移动的距离/遮罩层最大移动距离

      大图片移动距离 = 遮罩层移动的距离 ∗ 大图片最大可移动距离 / 遮罩层最大移动距离 大图片移动距离 = 遮罩层移动的距离 * 大图片最大可移动距离 / 遮罩层最大移动距离 大图片移动距离=遮罩层移动的距离大图片最大可移动距离/遮罩层最大移动距离

  2. 在最后根据遮罩层的移动而移动大图片的时候,一定要记得在css部分加上大图片自己的定位(position: absolute; top: 0; left: 0;)这样才能在移动的时候修改 top 和 left 值。

  3. 在script中给css的 top 和 left 属性赋值时一定记得加单位(px)

四、代码

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
            html {
                height: 1200px;
            }
            .w {
                width: 1200px;
                margin: 0 auto;
            }
            .preview {
                position: relative;
                top: 100px;
                height: 398px;
                width: 398px;
                border: 1px solid #ccc;
            }
            .mask {
                display: none;
                position: absolute;
                top: 0;
                left: 0;
                width: 300px;
                height: 300px;
                background-color: #fede4f;
                opacity: 0.5;
                border: 1px solid #ccc;
                cursor: move;
            }
            .big {
                display: none;
                overflow: hidden;
                position: absolute;
                left: 410px;
                top: 0;
                width: 500px;
                height: 500px;
                z-index: 999;
                border: 1px solid #ccc;
            }
            .bigImg {
                position: absolute;
                top: 0;
                left: 0;
            }
        </style>
    </head>
    <body>
        <div class="w">
            <div class="preview">
                <img src="img/s3.png" alt="" />
                <div class="mask"></div>
                <div class="big">
                    <img src="img/big.jpg" alt="" class="bigImg" />
                </div>
            </div>
        </div>
        <script>
            // 获取元素
            var preview = document.querySelector(".preview");
            var mask = document.querySelector(".mask");
            var big = document.querySelector(".big");
            var bidImg = document.querySelector(".bigImg");
            // 鼠标移入展示遮罩层和大图
            preview.addEventListener("mouseover", function (e) {
                mask.style.display = "block";
                big.style.display = "block";
            });
            // 鼠标移出隐藏遮罩层和大图
            preview.addEventListener("mouseout", function (e) {
                mask.style.display = "none";
                big.style.display = "none";
            });
            preview.addEventListener("mousemove", function (e) {
                // 鼠标在盒子内的坐标
                var x = e.pageX - this.offsetLeft;
                var y = e.pageY - this.offsetTop;
                // 遮罩层的移动距离,减去mask的一半宽高是为了让鼠标位于mask中间
                var maskX = x - mask.offsetWidth / 2;
                var maskY = y - mask.offsetHeight / 2;

                // 遮罩层最大移动距离
                var maskMax = preview.offsetHeight - mask.offsetHeight;
                // 遮罩层最大移动距离,不能超过父盒子
                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";
                // 大图的最大移动距离
                var bigMax = big.offsetWidth - bidImg.offsetWidth;
                // 大图的移动距离 = 大图最大移动距离 * 遮罩层移动距离 / 遮罩层最大移动距离
                var bigX = (maskX * bigMax) / maskMax;
                var bigY = (maskY * bigMax) / maskMax;
                bidImg.style.left = bigX + "px";
                bidImg.style.top = bigY + "px";
            });
        </script>
    </body>
</html>

五、图片

  1. 小图
    小图片
  2. 大图
    大图
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值