js magnifying glass (object-oriented)

Insert picture description here

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>放大镜</title>
    <script src="util.js"></script>
    <style>
        * {
     
     
            margin: 0;
            padding: 0;
        }

        body {
     
     
            height: 2000px;
        }

        .box {
     
     
            width: 450px;
            margin: 50px;
            display: flex;
            flex-direction: column;
            position: relative;
        }

        .box>.show {
     
     
            width: 420px;
            height: 430px;
            border: 1px solid #333;
            position: relative;
            text-align: center;
        }

        .box>.show>img {
     
     
            width: 100%;
            height: 100%;
        }

        .box>.show>.mask {
     
     
            width: 100px;
            height: 100px;
            background-color: yellow;
            opacity: .4;
            position: absolute;
            top: 0px;
            left: 0px;

            display: none;
        }

        .box>.list {
     
     
            width: 100%;
            flex: 1;

            display: flex;
            justify-content: flex-start;
            align-items: center;
            box-sizing: border-box;
            padding: 20px;
        }

        .box>.list>p {
     
     
            width: 60px;
            height: 60px;
            border: 2px solid #333;
            margin-right: 10px;
            text-align: center;
        }

        .box>.list>p.active {
     
     
            border-color: red;
        }

        .box>.enlarge {
     
     
            width: 500px;
            height: 500px;
            position: absolute;
            top: 0px;
            left: 450px;
            background-size: 750px 1000px;
            background-position: 0 0;
            background-repeat: no-repeat;
            border: 1px solid #ccc;
            background-image: url(./images/img1_750x1000.jpg);
            display: none;
        }
    </style>
</head>

<body>
    <div class="box">
        <div class="show">
            <img src="./images/img1_430x430.jpg">
            <div class="mask"></div>
        </div>
        <div class="list">
            <p class="active">
                <img midelImg="./images/img1_430x430.jpg" bigImg="./images/img1_750x1000.jpg"
                    src="./images/img1_60x60.jpg">
            </p>
            <p>
                <img midelImg="./images/img2_430x430.jpg" bigImg="./images/img2_750x1000.jpg"
                    src="./images/img2_60x60.jpg">
            </p>
            <p>
                <img midelImg="./images/img3_430x430.jpg" bigImg="./images/img3_750x1000.jpg"
                    src="./images/img3_60x60.jpg">
            </p>
            <p>
                <img midelImg="./images/img4_430x430.jpg" bigImg="./images/img4_750x1000.jpg"
                    src="./images/img4_60x60.jpg">
            </p>
            <p>
                <img midelImg="./images/img5_430x430.jpg" bigImg="./images/img5_750x1000.jpg"
                    src="./images/img5_60x60.jpg">
            </p>
        </div>
        <div class="enlarge"></div>
    </div>

    <script>
        /*  
        【1】创建对象
        【2】描述对象
            静态属性 .box||#box
            动态属性 
                init() 初始化   
                move() 放大镜移动
                changeImg() 点击下方小图打开大图
                setStyle() 计算放大镜盒子的宽高(与放大镜区域成比例)
        【3】调用 new Enlarge('.box')
         */

        class Enlarge {
     
     
            constructor(str) {
     
     
                this.str = str;
                this.init();
            }
            init() {
     
     
                // 获取元素
                // this.show=document.querySelector(this.str+" .show")
                this.box = document.querySelector(this.str);
                this.show = this.box.querySelector(".show");
                this.img = this.show.querySelector('img');
                this.mask = this.show.querySelector('.mask'); //放大镜
                this.list = this.box.querySelector('.list');
                this.p = this.list.children;
                this.enlarge = this.box.querySelector('.enlarge') //放大图片显示的容器

                // 绑定事件
                // 鼠标移入事件
                this.show.onmouseover = () => {
     
     
                    this.mask.style.display = this.enlarge.style.display = 'block';
                    this.setStyle();
                }
                // 鼠标移出事件
                this.show.onmouseout = () => {
     
     
                    this.mask.style.display = this.enlarge.style.display = 'none';
                }
                // 鼠标在show中的移动事件
                this.show.onmousemove = (e) => {
     
     
                    this.move(e);
                }
                // 给下方每个小图绑定点击事件
                [...this.p].forEach((item) => {
     
     
                    item.onclick = () => {
     
     
                        this.changeImg(item);
                    }
                })
            }
            setStyle() {
     
      //设置放大镜盒子的大小
                /* 
                    show盒子的大小      放大镜背景图的大小
                    -------------  == -------------------
                    mask盒子的大小      放大镜盒子的大小
                
                */
                //求出放大镜盒子的大小
                let arr = window.getComputedStyle(this.enlarge)['backgroundSize'].split(' ');
                // 放大镜区域背景图的宽高
                this.wid = parseInt(arr[0]);
                this.hei = parseInt(arr[1]);
                // 放大镜区域的宽高
                let l_width = this.wid * this.mask.offsetWidth / this.show.offsetWidth;
                let l_height = this.hei * this.mask.offsetHeight / this.show.offsetHeight;
                this.enlarge.style.width = l_width + 'px';
                this.enlarge.style.height = l_height + 'px';
            }
            move(e) {
     
     
                // 获取mask放大镜的位置
                let lef = e.clientX - this.box.offsetLeft - this.mask.offsetWidth / 2;
                let top = e.clientY - this.box.offsetTop - this.mask.offsetHeight / 2;
                // 判定边界
                if (lef <= 0) {
     
     
                    lef = 0;
                };
                if (top <= 0) {
     
     
                    top = 0;
                };
                if (lef >= this.show.offsetWidth - this.mask.offsetWidth) {
     
     
                    lef = this.show.offsetWidth - this.mask.offsetWidth;
                };
                if (top >= this.show.offsetHeight - this.mask.offsetHeight) {
     
     
                    top = this.show.offsetHeight - this.mask.offsetHeight;
                };
                // 赋值给放大镜的left top
                this.mask.style.left = lef + 'px';
                this.mask.style.top = top + 'px';


                // 背景图移动:
                /* 
                   mask的left         背景图移动的距离
                ---------------- == -------------------
                   show的宽度          背景图的宽度
                */
                // 求出背景图background-position
                let bgx = lef * this.wid / this.show.offsetWidth;
                let bgy = top * this.hei / this.show.offsetHeight;
                this.enlarge.style.backgroundPosition = `${
       
       -bgx}px ${
       
       -bgy}px`;

            }
            changeImg(pLi) {
     
      //切换图片
                let imgf = pLi.firstElementChild;
                // 添加active
                [...this.p].forEach((item) => {
     
     
                    item.classList.remove('active');
                })
                pLi.classList.add('active');
                // 获取中图
                let midel = imgf.getAttribute('midelImg');
                let big = imgf.getAttribute('bigImg');

                this.img.setAttribute('src', midel);
                this.enlarge.style.backgroundImage = `url(${
       
       big})`;

            }


        }


        new Enlarge('.box');
    </script>
</body>

</html>

Guess you like

Origin blog.csdn.net/qq_43812504/article/details/112687726