【前端入门】商品页放大镜效果(仅放大镜随鼠标移动效果)

摘要

依旧是offset系列属性练习。模仿京东放大商品的效果。

一、基本原理

1.利用e.pageX和e.pageY配合offsetTop、offsetLeft获得鼠标在容器内的位置

2.再将获得的位置信息赋值给放大镜的top,left属性

3.最后if条件语句控制放大镜的范围不要超出容器

二、实现过程

1.准备一个大盒子,里面插入商品图片;在准备一个盒子作为放大镜,定位在大盒子里面

ini 复制代码
<div class = "goods">
    <img src="mobile.jpg" alt = "手机"/>
    <div class = "mask"></div>
</div>

2.为盒子设置样式

xml 复制代码
<style>
    .goods{
        position:relative;
        width:300px;
        height:400px;
    }
    .goods img{
        width:300px;
        height:400px;
    }
    .mask{
        display:none;
        position:absolute;
        left:0px;
        top:0px;
        width:100px;
        height:100px;
        background-color:yellow;
        opacity:.3;
        cursor:move;
    }
</style>

*cursor:move;这行代码能使鼠标变成十字型

3.绑定事件(鼠标进入显示放大镜;鼠标离开隐藏放大镜;鼠标移动放大镜跟着移动)

ini 复制代码
<script>
    var goods = document.querySelector(".goods");
    var mask = document.querySelector(".mask");
    goods.addEventListener("mouseenter",function(){
        mask.style.display = "block";
    })
    goods.addEventListener("mouseleave",function(){
        mask.style.display = "none";
    })
    goods.addEventListener("mousemove",function(e){
        var x = e.pageX - this.offsetLeft;
        var y = e.pageY - this.offsetTop;
        var maskX = x - mask.offsetWidth/2;
        var maskY = y - mask.offsetHeight/2;
        if(maskX <= 0){
            maskX = 0;
        }
        else if (maskX >= goods.offsetWidth - mask.offsetWidth){
            maskX = goods.offsetWidth - mask.offsetWidth;
        }
        if(maskY <= 0){
            maskY = 0;
        }
        else if (maskY >= goods.offsetHeight - mask.offsetHeight){
            maskY = goods.offsetHeight - mask.offsetHeight;
        }
        mask.style.left = maskX + 'px';
        mask.style.top = maskY  + 'px';
    })
</script>

a.代码第13、14行的用意是使鼠标始终在放大镜中央,更美观

b.27、28行,在设置top和left属性时一定不要忘记加单位

c.mouseenter与mouseover相比没有冒泡,不会产生冗余事件

三、完整代码示例

xml 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模拟京东放大镜效果</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        .goods {
            position: relative;
            margin: 100px auto;
            width: 285px;
            height: 292px;
            border: 1px solid #999;
        }

        .goods img {
            width: 283px;
            height: 290px;
        }

        .mask {
            display: none;
            position: absolute;
            left: 0px;
            top: 0px;
            width: 150px;
            height: 150px;
            background-color: rgb(248, 220, 10);
            opacity: .4;
            cursor: move;
        }
    </style>
</head>

<body>
    <div class="goods">
        <img src="../shopping/upload/mobile.jpg" alt="">
        <div class="mask"></div>
    </div>
    <script>
        var goods = document.querySelector(".goods");
        var mask = document.querySelector(".mask");
        goods.addEventListener("mouseover", function () {
            mask.style.display = 'block';
        })
        goods.addEventListener("mouseout", function () {
            mask.style.display = 'none';
        })
        goods.addEventListener("mousemove", function (e) {
            var x = e.pageX - this.offsetLeft;
            var y = e.pageY - this.offsetTop;
            var maskX = x - mask.offsetWidth / 2;
            var maskY = y - mask.offsetHeight / 2;
            if (maskX <= 0) {
                maskX = 0;
            } else if (maskX >= goods.offsetWidth - mask.offsetWidth) {
                maskX = goods.offsetWidth - mask.offsetWidth;
            }
            if (maskY <= 0) {
                maskY = 0;
            } else if (maskY >= goods.offsetHeight - mask.offsetHeight) {
                maskY = goods.offsetHeight - mask.offsetHeight;
            }
            mask.style.left = maskX + 'px';
            mask.style.top = maskY + 'px';

        })
    </script>
</body>

</html>
相关推荐
毛骗导演12 分钟前
@tencent-weixin/openclaw-weixin 源码ContextToken 持久化改造:实现微信自定义消息发送能力
前端·架构
爱丽_12 分钟前
Pinia 状态管理:模块化、持久化与“权限联动”落地
java·前端·spring
SuperEugene40 分钟前
TypeScript+Vue 实战:告别 any 滥用,统一接口 / Props / 表单类型,实现类型安全|编码语法规范篇
开发语言·前端·javascript·vue.js·安全·typescript
我是永恒1 小时前
上架一个跨境工具导航网站
前端
电子羊1 小时前
Spec 编程工作流文档
前端
GISer_Jing1 小时前
从CLI到GUI桌面应用——前端工程化进阶之路
前端·人工智能·aigc·交互
还是大剑师兰特2 小时前
Vue3 报错:computed value is readonly 解决方案
前端·vue.js
leaves falling2 小时前
有效的字母异位词
java·服务器·前端
We་ct2 小时前
LeetCode 35. 搜索插入位置:二分查找的经典应用
前端·算法·leetcode·typescript·个人开发
左耳咚2 小时前
Claude Code 中的 SubAgent
前端·ai编程·claude