用 js 实现购物网站中的商品放大镜效果

news/2024/7/19 13:02:19 标签: js, 前端, javascript

首先说一下原理,以天猫某商品放大镜效果为例:
在这里插入图片描述所谓的放大镜效果,其实也是欺骗我们眼球的一种效果,这里我们可以看到,图片显示去下面那一排小图与遮盖层的图片和放大层的图片其实是一样的,只是分辨率不同,所以实现放大镜效果,就需要这么几组分辨率大小不同,但是图片内容相同的图片:
在这里插入图片描述显然,小图中放的就是我这里图片名中带有small的小图了,遮盖层就是正常大小的图,放大层就是带有big的放大的图了,然后再加入适当的位移和显示效果,就达成我们见到的放大镜效果了,下面就通过代码来实现吧:
首先写出HTML结构:

 <div id="box">
    <div class="show">
        <img src="./images/1.jpg" alt="#">
        <div class="drag"></div>
    </div>
    <div class="magnify"></div>
    <ul>
        <li class="active"><img src="./images/1.small.jpg" alt="#"></li>
        <li><img src="./images/2.small.jpg" alt="#"></li>
    </ul>
</div>

<script type="text/javascript" src="./javascript/mgfyGlass.js">javascript"></script>

<script>javascript">
    const oBox = document.querySelector('#box');
    
    const imgArr = [
        {small: '1.small.jpg', normal: '1.jpg', big: '1.big.jpg'},
        {small: '2.small.jpg', normal: '2.jpg', big: '2.big.jpg'}
    ];
</script>

然后加入css样式:

body,div,ul,li{
    margin: 0; padding: 0;
    list-style: none;
    font-size: 0;
}
img{
    display: block;
}
#box{
    width: 650px;
    position: relative;
    margin: 0 auto 0 240px;
}
#box .show{
    width: 600px;
    border: solid 2px hotpink;
    position: relative;
}
#box .show img{
    width: 100%;
}
#box .show .drag{
    position: absolute;
    width: 200px;
    height: 200px;
    background-color: #e0a8d7;
    opacity: .4;
    left: 0;
    top: 0;
    display: none;
}
#box .magnify{
    width: 800px;
    height: 800px;
    border: solid 2px #7d777b;
    position: absolute;
    left: 100%;
    top: 0;
    background: url("../images/1.big.jpg") no-repeat 0 0 / 2400px;
    display: none;
}
#box ul{
    width: 100%;
    height: 150px;
    margin-top: 20px;
}
#box ul::after{
    content: '';
    display: block;
    clear: both;
}
#box ul li{
    height: 100%;
    float: left;
    margin: 0 8px;
    border: solid 2px #fff;
}
#box ul li.active{
    border-color: hotpink;
}
#box ul li img{
    height: 100%;
}

这里设置css样式的时候需要注意:

放大层是通过遮盖层等比放大的,所以放大层的宽高与遮盖层宽高的比,和,放大层背景图大小与正常显示图片(也就是class=“show” 盒子中的图片)大小的比是相同的。

这里需要用js来实现几个效果:

  1. 鼠标移入正常图片盒子时遮盖层和放大层盒子显示,鼠标移出正常图片盒子时遮盖层和放大层盒子隐藏
  2. 定位遮盖层位置,让它随着鼠标在 正常图片盒子 内移动,同时放大层图片对应的在放大层盒子内移动
  3. 设置小图切换效果,并在小图切换的同时,正常图片和放大图切换到对应图片

然后上代码:

javascript">class MgnGlass {
    constructor(ele, array) {
        this.ele = ele;
        this.array = array;

        this.show = ele.querySelector('.show');
        this.showImg = this.show.querySelector('img');
        this.drag = ele.querySelector('.drag');
        this.magnify = ele.querySelector('.magnify');
        this.oUl = ele.querySelector('ul');
        this.oUlis = ele.querySelectorAll('ul li');
    }

	// 定义一个方法,来调用之后定义的所有的方法
    // 入口函数
    init() {
        this.setMouse();
        this.setPosition();
        this.setTab();
    }

    // 鼠标的移入移出
    setMouse() {
    	// 鼠标移入,图片区域show,让遮盖层和放大镜显示
        this.show.addEventListener('mouseover', () => {
            this.drag.style.display = 'block';
            this.magnify.style.display = 'block';
        });
        // 鼠标移出,图片区域show,让遮盖层和放大镜隐藏
        this.show.addEventListener('mouseout', () => {
            this.drag.style.display = 'none';
            this.magnify.style.display = 'none';
        });
    }

	// 设置定位效果
	// 鼠标在 图片区域移动 时
    // 1,让遮盖层,跟随鼠标移动 --- 类似之前鼠标拖拽的效果
    setPosition() {
        this.show.addEventListener('mousemove', (e) => {
            e = e || event;
            // 1,定位 遮盖层
            // 通过 鼠标的定位位置,来计算 遮盖层 左上角 定位的坐标位置
            let x = e.clientX - this.ele.offsetLeft - this.ele.clientLeft - this.drag.clientWidth / 2;
            let y = e.clientY - this.ele.offsetTop - this.ele.clientTop - this.drag.clientHeight / 2;

			// 2,设定边界值
            // 最小是 0  最大值 父级div宽高 - 遮盖层宽高
            if (x < 0){
                x = 0;
            }
            else if (x > (this.show.clientWidth - this.drag.clientWidth)){
                x = this.show.clientWidth - this.drag.clientWidth;
            }
            if (y < 0){
                y = 0;
            }
            else if (y > (this.show.clientHeight - this.drag.clientHeight)){
                y = this.show.clientHeight - this.drag.clientHeight;
            }

			// 3,将数值定位给遮盖层
            this.drag.style.left = x + 'px';
            this.drag.style.top = y + 'px';

			// 4,需要让右侧放大镜的背景图片也一起移动
            // 给背景图片添加定位
            // 左侧是 图片不动,遮盖层动      遮盖层动  100  100
            // 右侧是 放大镜不动,背景图片动  背景图动 -100 -100
            // 移动时,定位必须是按照比例来设定

			// 背景图片定位 = 背景图片大小 * 遮盖层定位 / 图片大小 
            // 通过遮盖层移动的比例,来计算,背景图片定位的数值
            let backX = 2400 * x / 600;
            let backY = 2400 * y / 600;

			// 给背景图片定位
            // 给背景图片进行定位赋值操作
            this.magnify.style.backgroundPosition = `-${backX}px -${backY}px`;
        })
    }

	// 切换效果
    // 1,给当前鼠标经过mouseover 的标签,添加样式
    //   给所有的标签去除样式,给当前点击/经过标签,添加样式
    setTab() {
        this.oUlis.forEach((item, key) => {
            item.addEventListener('mouseover', () => {
            	// 1,给所有的li标签清除样式
                this.oUlis.forEach((item2) => {
                    item2.className = '';
                });
                // 2,给当前的标签添加样式
                item.className = 'active';

				// 3,设定图片
                // 当前标签的索引下标 key 就是对应 图片数组中,需要显示的图片的索引下标
                
                // 1,给图片标签,设定路径
                // 通过数组,索引,图片属性,获取对应的图片名称
                // 标签.src = 赋值   或者  标签.setAttribute('src' , 属性值) 都可以
                this.showImg.setAttribute('src', `./images/${this.array[key].normal}`);
                // 2,给放大镜区域,背景图片设定路径
                // 必须把关于背景图片的所有设定都重新写一遍
                this.magnify.style.background = `url('./images/${this.array[key].big}') no-repeat 0 0 / 2400px`;
            })
        })
    }
}

要完美实现放大镜效果,必须注意2个比例

  1. CSS样式的比例 : 图片区域大小 : 遮盖层大小 = 背景图片大小 : 放大镜区域大小
  2. 定位的比例 : 遮盖层定位 : 图片区域大小 = 背景图片定位 : 背景图片大小

然后在调用我们的构造函数即可得到最终的HTML,执行即可达到我们的放大镜效果了:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>放大镜</title>
    <link rel="stylesheet" type="text/css" href="./css/mgfyGlass.css">
</head>
<body>
    <div id="box">
        <div class="show">
            <img src="./images/1.jpg" alt="#">
            <div class="drag"></div>
        </div>
        <div class="magnify"></div>
        <ul>
            <li class="active"><img src="./images/1.small.jpg" alt="#"></li>
            <li><img src="./images/2.small.jpg" alt="#"></li>
        </ul>
    </div>

    <script type="text/javascript" src="./javascript/mgfyGlass.js">javascript"></script>

    <script>javascript">
        const oBox = document.querySelector('#box');
        
        const imgArr = [
            {small: '1.small.jpg', normal: '1.jpg', big: '1.big.jpg'},
            {small: '2.small.jpg', normal: '2.jpg', big: '2.big.jpg'}
        ];
        
        const mgnGlass = new MgnGlass(oBox, imgArr);
    
        mgnGlass.init();
    
    
    </script>
</body>
</html>

http://www.niftyadmin.cn/n/1110693.html

相关文章

SLF4j 和 common-logging

Apache Common-Logging是广泛使用的Java日志门面库。我以前一直都使用它和log4j编写日志。 Apache Common-Logging通过动态查找的机制&#xff0c;在程序运行时自动找出真正使用的日志库。 Apache Common-Logging一直都运作得很好。直到最近&#xff0c;我写OSGI插件时&#…

ajax请求及其用法详解

什么是ajax 首先&#xff0c;ajax中的四个字母的意思分别是&#xff1a; a : async 异步 j : JavaScript a : and x : XML ajax请求是一个异步的 JavaScript 和 XML 的数据交互 ajax技术最初只能和 XML格式的内容进行交互 现在发展到可以和任意的后端程序内容进行交互 现在是…

Linux下的多媒体软件(转)

Linux下的多媒体软件(转)[more]  Linux以其强大的服务器功能著称&#xff0c;近年来逐渐流行并进入个人领域&#xff0c;但许多用户并不了解Linux下的软件&#xff0c;以为它只是用在网络服务器上&#xff0c;其实它在多媒体领域也有相当全面的支持。这里就介绍几款linux下的…

nodejs 保存 payload 发送过来的文件

1&#xff1a;接受文件 http://stackoverflow.com/questions/24610996/how-to-get-uploaded-file-in-node-js-express-app-using-angular-file-upload 可以用下列的第三方库 busboy and connect-busboymultiparty and connect-multipartyformidablemulter2&#xff1a;保存文件…

了解jQuery ,jQuery 选择器和筛选器总结

在说选择器和筛选器之前&#xff0c;首先我们来了解一下什么是jQuery&#xff1a; jQuery 的简介 什么是jQuery jQuery是 一个前端的方法库 也就是别人将JavaScript程序,定义成了各种函数方法,我们直接写直接用,就可以实现各种功能 jQuery的网站 官网 : https://jquery.co…

Jedit for Linux 开发版(转)

Jedit for Linux 开发版(转)[more]jedit是一个用java编写的源码开放的文本编辑器。它支持超过30种的文件类型并能根据不同文件显示不同的关键字颜色&#xff0c;其中当然包括C、C、JAVA、PERL、HTML等等。它还能自动对行进行缩进(INDENT)&#xff0c;强大的宏功能可以使你方便的…

瑞丽的SQL-SQL Server的表旋转(行列转换)

所谓表旋转&#xff0c;就是将表的行转换为列&#xff0c;或是将表的列转换为行&#xff0c;这是从SQL Server 2005開始提供的新技术。因此&#xff0c;如果希望使用此功能&#xff0c;须要将数据库的兼容级别设置为90。表旋转在某些方面也是攻克了表的数据存储和实际须要之间的…

木马的十大藏身地点(转)

木马的十大藏身地点(转)[more]木马是一种基于远程控制的病毒程序&#xff0c;该程序具有很强的隐蔽性和危害性&#xff0c;它可以在人不知鬼不觉的状态下控制你或者监视你。有人说&#xff0c;既然木马这么厉害&#xff0c;那我离它远一点不就可以了&#xff01; 然而这个木马实…