JavaScript 放大镜(面向对象)

本文介绍了一段使用HTML和JavaScript构建的网页,展示了如何通过JavaScript实现图片放大镜效果,包括遮盖层、放大区和背景图的交互,以及响应式布局。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

放大镜效果展示:

 

HTML代码:

<!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;
        }
        li{
            list-style: none;
        }
        a{
            text-decoration: none;
        }
        img{
            display: block;
            width: 100%;
            height: 100%;
        }
        .box{
            
            width: 900px;
            margin: 50px auto;
            position: relative;
        }
        .exhibition{
            width: 400px;
            height: 400px;
            border: 2px solid black;
            box-shadow: 0px 0px 3px 1px black;
            
        }
        .exhibition .overspread{
            width: 100px;
            height: 100px;
            background-color: rgb(224, 224, 18,0.5);
            position: absolute;
            left: 0;
            top: 0;
            display: none;
        }
        .sol{
            width: 400px;
            height: 200px;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        .sol li{
            width: 100px;
            height: 100px;
        }
        .active{
            border: 1px solid red;
        }
        .glass{
            width: 400px;
            height: 400px;
            border: 1px solid black;
            position: absolute;
            left: 450px;
            top: 0;
            display: none;
            /* background-image: url(./images/1.large.jpg); */
            background-size: 1600px 1600px;

        }
    </style>
</head>
<body>
    <div class="box">
       
    </div>
    <script src="./glass.js"></script>
    <script>
        // 数组模拟后端传参
        const arr = [{big:"./images/1.large.jpg",small:"./images/1.small.jpg"},
                     {big:"./images/2.large.jpg",small:"./images/2.small.jpg"},
                     {big:"./images/3.large.jpg",small:"./images/3.small.jpg"}];
        // 获取标签对象
        const oDiv = document.querySelector(".box");
        // 面向对象编程
        // 调用 构造函数 生成 实例化对象
        const glass = new CreateFunction(oDiv,arr);
        // 入口函数
        glass.init();
        // 页面放大缩小事件监听
        window.addEventListener("resize",function(){
            glass.getSize();
        })
    </script>
</body>
</html>

JavaScript代码:

class CreateFunction{
    constructor(element,ImgArr){
        // 定义属性 存储 形参
        this.ele = element;
        this.arr = ImgArr;
        // 全局变量
        this.exhi;
        this.over;
        this.oImg;
        this.oSol;
        this.glass;
        this.imgArr;

        // 存储 标签 占位属性 
        this.marginLeft;
        this.marginTop;
       
        this.borderLeft;
        this.borderTop;
       
        this.exhiWidth;
        this.exhiHeight;
       
        this.overWidth;
        this.overHeight;
    }
    // 入口函数
    init(){
        this.setPage();
        this.mouseShow();
        this.mouseList();
        this.mouseMove();
    }
    // 动态生成
    setPage(){
        // 创建标签节点
        this.exhi = document.createElement("div");
        this.over = document.createElement("div");
        this.oImg = document.createElement("img");
        this.oSol = document.createElement("ul");
        this.glass = document.createElement("div");
        // 添加class属性
        this.exhi.classList.add("exhibition");
        this.over.classList.add("overspread");
        this.oSol.classList.add("sol");
        this.glass.classList.add("glass")
        // 添加节点
        this.exhi.appendChild(this.oImg);
        this.exhi.appendChild(this.over);
        this.ele.appendChild(this.exhi)
        this.ele.appendChild(this.oSol)
        this.ele.appendChild(this.glass)
        // 动态写入内容
        var liStr = "";
        this.arr.forEach((item,key)=>{
            liStr += key === 0 ? `<li   ><img num = "${key}" class="active" src="${item.small}" alt=""></li>`:`<li ><img num = "${key}" src="${item.small}" alt="" ></li>`;
            this.oSol.innerHTML = liStr;
        });
        // 设定 ul>li 中img 标签 图片内容
        // 设定 img标签 src 属性的属性值
            this.oImg.setAttribute( 'src' , `${this.arr[0].big }` );
        // 设定 glass中的背景图样式
        // 标签的 background-image css样式属性
            this.glass.style.backgroundImage = `url(./${this.arr[0].big })`;
        // 获取生成的li>img标签的伪数组
        this.imgArr = this.oSol.querySelectorAll("img");

        // 获取占位数据
        // 外边距
        this.marginLeft = this.ele.offsetLeft ;
        this.marginTop = this.ele.offsetTop ;
        // 边框宽度
        this.borderLeft = this.exhi.clientLeft ;
        this.borderTop = this.exhi.clientTop ;
        // 内容+padding
        this.exhiWidth = this.exhi.clientWidth ;
        this.exhiHeight = this.exhi.clientHeight ;
        // 遮盖层 宽高
        this.overWidth = parseInt(window.getComputedStyle(this.over).width);
        this.overHeight = parseInt(window.getComputedStyle(this.over).height);
        
    }
        // 鼠标移入显示遮盖层和放大镜
        mouseShow(){
        // 鼠标移入 show 显示 遮盖层和放大镜
        // 使用 mouseenter 事件类型
            this.exhi.addEventListener("mouseenter",()=>{
                this.glass.style.display = "block";
                this.over.style.display = "block";
            })
        // 鼠标移出 show 隐藏 遮盖层和放大镜
        // 使用 mouseleave 事件类型
            this.exhi.addEventListener("mouseleave",()=>{
                this.glass.style.display = "none";
                this.over.style.display = "none";
            })
        }
        // 鼠标经过列表区
        mouseList(){
            // 当鼠标经过ul区域
            this.oSol.addEventListener("click",e => {
                if(e.target.tagName === "IMG"){
                    // 清除所有class
                    this.imgArr.forEach(item =>{
                        item.classList.remove("active");
                    })
                    // 给点击的标签对象添加class
                    e.target.classList.add("active");
                }
                // 设定 放大镜 背景图片 css样式
                this.glass.style.backgroundImage = `url(./${this.arr[Number(e.target.getAttribute("num"))].big })`;
                 // 设定 oImg中img标签 src属性值
                // 图片 是 当前标签num属性存储的属性值 也就是 索引下标 
                this.oImg.setAttribute( 'src' , `${this.arr[Number(e.target.getAttribute("num"))].big }` );
            })
        }
        // 鼠标拖拽效果
        mouseMove(){
            this.exhi.addEventListener("mousemove",e =>{
                // 给 exhi 添加 鼠标移动事件mousemove
                // 页面滚动 放大镜一起滚 使用 事件对象.pageX 获取鼠标坐标 
                let x = e.pageX - this.marginLeft - this.borderLeft - this.overWidth/2 ;
                let y = e.pageY - this.marginTop - this.borderTop - this.overHeight/2 ;
                // 计算极值
                x  = x < 0 ? 0 : x ;
                y = y < 0 ? 0 : y ;
                x = x > this.exhiWidth - this.overWidth ? this.exhiWidth - this.overWidth : x;
                y = y > this.exhiHeight - this.overHeight ?  this.exhiHeight - this.overHeight : y;
                // 将设定好的数值 赋值给 mask标签的定位
                this.over.style.left = x +'px';
                this.over.style.top = y +'px';
                // 给 背景图片 做 定位
                // 背景图片定位方向 和遮盖层拖拽方向相反
                // 背景图片定位数值 和遮盖层拖拽数值成等比例关系 当前 是 1:4 
                this.glass.style.backgroundPosition = `${-x*4}px ${-y*4}px`;
            })
        }

        // 重新获取数据函数
        // 这个函数不用一开始就执行 不写入 init()
        // 只有页面大小改变时 再触发执行
        getSize(){
              // 获取占位数据
        // 外边距
        this.marginLeft = this.ele.offsetLeft ;
        this.marginTop = this.ele.offsetTop ;
        // 边框宽度
        this.borderLeft = this.exhi.clientLeft ;
        this.borderTop = this.exhi.clientTop ;
        // 内容+padding
        this.exhiWidth = this.exhi.clientWidth ;
        this.exhiHeight = this.exhi.clientHeight ;
        // 遮盖层 宽高
        this.overWidth = parseInt(window.getComputedStyle(this.over).width);
        this.overHeight = parseInt(window.getComputedStyle(this.over).height);
        }



}

页面结构: 

 注意点:

遮盖层        放大区

------ ===== -------

显示区        背景图     

原始比例相等!!!

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大聪明码农徐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值