百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

使用原生js、css和html实现图片画廊组件

zhezhongyun 2024-12-26 17:41 67 浏览

图片画廊组件是网站中常见的UI组件,尤其是在电商平台的产品详情页上,它允许用户通过缩略图快速浏览和查看产品的多个图片。本文介绍如何仅使用原生的js、css和html实现下面动画呈现的图片画廊组件。

功能介绍

  1. html结构中上方为主图区域,下方为缩略图列表,缩略图列表的两边为控制水平左右滑动的箭头导航;
  2. 鼠标移动到某个缩略图上时,主图区域将显示缩略图的大图,并且缩略图着红色边框以突出显示;
  3. 点击右侧箭头,缩略图向左侧滑动直到最右侧的缩略图显示在视野中,此时右侧箭头失效;类似的,点击左侧箭头,缩略图向右侧滑动直到最左侧缩略图出现在视野中,此时左侧箭头失效。

HTML结构

首先创建HTML结构,包括主图区域和下方导航区域,需要重点交代的是id为spec-list的div元素是缩略图列表的容器,容器的position属性是relative,设置了固定的宽度,overflow设置为hidden,这样其子元素超过宽度的部分将不可见,它就相当于窗户,提供了一个矩形的的可见视野。ul装载所有的缩略图,它的position属性设置为absolute,这样就可以基于其父元素设置偏移量,它的宽度大于父元素的宽度,这样就通过设置left属性实现左右滑动,在父窗口范围内的缩略图将是可见的,这样就实现了滑动效果。

<div class="product-intro">
	<div class="preview-wrap">
		<div class="preview" id="preview">
			<!-- 主图显示区域 -->
			<div class="main-img" style="width: 460px; height: 460px;">
				<img id="spec-img" alt="" src="./images/ai-generated-8833166_1280.webp" 
					style="width: 100%; height: 100%; object-fit: cover;">
			</div>

			<!-- 下方导航列表 -->
			<div class="spec-list" style="width: 452px;">
				<!-- 左侧箭头 -->
				<a id="spec-forward" href="javascript:;" class="arrow-prev disabled">
					<i class="sprite-arrow-prev">
						<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 24 24" style="scale:2;">
							<path fill="currentColor" fill-rule="evenodd" d="m15 4l2 2l-6 6l6 6l-2 2l-8-8z"/>
						</svg>
					</i>
				</a>
				<!-- 右侧箭头 -->
				<a id="spec-backward" href="javascript:;" class="arrow-next">
					<i class="sprite-arrow-next">
						<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 24 24" style="scale:2;">
							<path fill="currentColor" fill-rule="evenodd" d="m9.005 4l8 8l-8 8L7 18l6.005-6L7 6z"/>
						</svg>
					</i>
				</a>
				<!-- 缩略图列表可见区域 -->
				<div id="spec-list" class="spec-items"
					style="position: relative; width: 380px; height: 58px; overflow: hidden;">
					<!-- 缩略图列表 -->
					<ul class="lh" style="position: absolute; width: 456px; height: 58px; top: 0px; left: 0px;">
						<li class="img-hover"><img alt="" src="./images/ai-generated-8833166_1280.webp" width="54" height="54"></li>
						<li class=""><img alt="" src="./images/owl-50267_1280.jpg" width="54" height="54"></li>
						<li class=""><img alt="" src="./images/seal-8834240_1280.webp" width="54" height="54"></li>
						<li class=""><img alt="" src="./images/stork-8830107_1280.webp" width="54" height="54"></li>
						<li class=""><img alt="" src="./images/triggerfish-8832563_1280.webp" width="54" height="54"></li>
						<li class=""><img alt="" src="./images/ai-generated-8834126_1280.webp" width="54" height="54"></li>
					</ul>
				</div>
			</div>
		</div>
	</div>
</div>

CSS样式

.product-intro {
    position: relative;
    z-index: 1;
    margin-top: 10px;
    padding-bottom: 10px
}

.product-intro .preview-wrap {
    float: left;
    padding-bottom: 15px;
    position: relative;
    zoom:1;
    z-index: 7
}

.preview {
    position: relative
}

.preview .main-img {
    border: 1px solid #eee;
    margin-bottom: 20px;
    zoom: 1
}

.preview svg {
    color: #CCCCCC;
}

.preview .spec-list {
    margin-bottom: 18px;
    position: relative;
    zoom: 1
}

.preview .spec-list ul {
    margin: 0;
    transition: left 0.5s ease;
    list-style-type: none;
    padding-left: 0;
}

.preview .spec-list .arrow-next,.preview .spec-list .arrow-prev {
    display: block;
    width: 22px;
    height: 32px;
    float: left;
    position: absolute;
    cursor: pointer;
    top: 50%;
    margin-top: -16px
}

.preview .spec-list .arrow-next i,.preview .spec-list .arrow-prev i {
    display: block
}

.preview .spec-list .arrow-prev {
    left: 0
}

.preview .spec-list .arrow-prev:hover i svg {
    color: #999999;
}

.preview .spec-list .arrow-prev.disabled i svg {
    color: #DFDFDF;
}

.preview .spec-list .arrow-next {
    right: 0
}

.preview .spec-list .arrow-next:hover i svg {
    color: #999999;
}

.preview .spec-list .arrow-next.disabled i svg {
    color: #DFDFDF;
}

.preview .spec-items {
    width: 224px;
    margin: 0 auto;
    overflow: hidden
}

.preview .spec-items ul {
    width: 2000px
}

.preview .spec-items ul li {
    float: left;
    margin: 0 9px;
    max-width: 60px;
    max-height: 70px
}

.preview .spec-items ul li img {
    border: 2px solid #fff;
    padding-bottom: 1px
}

.preview .spec-items ul li.img-hover img,.preview .spec-items ul li:hover img {
    border: 2px solid #e53e41
}

.preview #spec-img {
    max-height: 600px;
}

.preview .spec-list .spec-items {
    width: 390px
}

JavaScript交互

js主要处理鼠标hover到缩略图更新主图区域图片的src属性值,以及缩略图的红色边框效果;以及实现左右侧箭头点击产生的缩略图列表左右滑动效果、箭头失效处理,注意js中是直接设置ul的left属性值,要实现滑动的动画效果,需要在css样式中设置transition属性为left 0.5s ease,否则就不会产生动画效果。

(function() {
    // 监听缩略图的鼠标进入事件,更新显示大图
    var thumbnail_img_list = document.querySelectorAll("#spec-list ul li img");
    var spec_img = document.getElementById("spec-img");
    for (let i=0; i < thumbnail_img_list.length; i++) {
        let thumbnail_img = thumbnail_img_list[i];
        thumbnail_img.addEventListener("mouseenter", function(e) {
            // 移除当前img-hover类
            let img_pre_hoverd = document.querySelector("#spec-list ul li.img-hover");
            if (img_pre_hoverd) {
                img_pre_hoverd.classList.remove("img-hover");
            }
            // 添加当前img-hover类
            e.target.parentNode.classList.add("img-hover");
            // 更新主图区域的图片源
            spec_img.src = thumbnail_img.src;
        });
    }

    // 缩略图的左右滑动效果
    var btn_next = document.getElementById("spec-backward");
    var btn_pre = document.getElementById("spec-forward");
    var spec_list = document.querySelector("#spec-list");
    var spec_list_ul = document.querySelector("#spec-list ul");
    
    // 监听右侧箭头的点击事件
    btn_next.addEventListener("click", function(e) {
        if (!this.classList.contains("disabled")) {
            // 点击右侧箭头,缩略图左侧滑动直到最右侧缩略图可见,即left为缩略图宽度-可见容器宽度,为负值
            spec_list_ul.style.left = (spec_list.clientWidth - spec_list_ul.clientWidth) + "px";

            // 右侧箭头失效
            this.classList.add("disabled");
            // 左侧箭头生效
            btn_pre.classList.remove("disabled");
        }
    });

    // 点击左侧箭头的点击事件
    btn_pre.addEventListener("click", function(e) {
        if (!this.classList.contains("disabled")) {
            // 点击左侧箭头,缩略图右侧滑动直到最左侧缩略图可见,即left为0
            spec_list_ul.style.left = "0px";

            // 左侧箭头失效
            this.classList.add("disabled");
            // 右侧箭头失效
            btn_next.classList.remove("disabled");
        }
    });

})();

相关推荐

Python入门学习记录之一:变量_python怎么用变量

写这个,主要是对自己学习python知识的一个总结,也是加深自己的印象。变量(英文:variable),也叫标识符。在python中,变量的命名规则有以下三点:>变量名只能包含字母、数字和下划线...

python变量命名规则——来自小白的总结

python是一个动态编译类编程语言,所以程序在运行前不需要如C语言的先行编译动作,因此也只有在程序运行过程中才能发现程序的问题。基于此,python的变量就有一定的命名规范。python作为当前热门...

Python入门学习教程:第 2 章 变量与数据类型

2.1什么是变量?在编程中,变量就像一个存放数据的容器,它可以存储各种信息,并且这些信息可以被读取和修改。想象一下,变量就如同我们生活中的盒子,你可以把东西放进去,也可以随时拿出来看看,甚至可以换成...

绘制学术论文中的“三线表”具体指导

在科研过程中,大家用到最多的可能就是“三线表”。“三线表”,一般主要由三条横线构成,当然在变量名栏里也可以拆分单元格,出现更多的线。更重要的是,“三线表”也是一种数据记录规范,以“三线表”形式记录的数...

Python基础语法知识--变量和数据类型

学习Python中的变量和数据类型至关重要,因为它们构成了Python编程的基石。以下是帮助您了解Python中的变量和数据类型的分步指南:1.变量:变量在Python中用于存储数据值。它们充...

一文搞懂 Python 中的所有标点符号

反引号`无任何作用。传说Python3中它被移除是因为和单引号字符'太相似。波浪号~(按位取反符号)~被称为取反或补码运算符。它放在我们想要取反的对象前面。如果放在一个整数n...

Python变量类型和运算符_python中变量的含义

别再被小名词坑哭了:Python新手常犯的那些隐蔽错误,我用同事的真实bug拆给你看我记得有一次和同事张姐一起追查一个看似随机崩溃的脚本,最后发现罪魁祸首竟然是她把变量命名成了list。说实话...

从零开始:深入剖析 Spring Boot3 中配置文件的加载顺序

在当今的互联网软件开发领域,SpringBoot无疑是最为热门和广泛应用的框架之一。它以其强大的功能、便捷的开发体验,极大地提升了开发效率,成为众多开发者构建Web应用程序的首选。而在Spr...

Python中下划线 ‘_’ 的用法,你知道几种

Python中下划线()是一个有特殊含义和用途的符号,它可以用来表示以下几种情况:1在解释器中,下划线(_)表示上一个表达式的值,可以用来进行快速计算或测试。例如:>>>2+...

解锁Shell编程:变量_shell $变量

引言:开启Shell编程大门Shell作为用户与Linux内核之间的桥梁,为我们提供了强大的命令行交互方式。它不仅能执行简单的文件操作、进程管理,还能通过编写脚本实现复杂的自动化任务。无论是...

一文学会Python的变量命名规则!_python的变量命名有哪些要求

目录1.变量的命名原则3.内置函数尽量不要做变量4.删除变量和垃圾回收机制5.结语1.变量的命名原则①由英文字母、_(下划线)、或中文开头②变量名称只能由英文字母、数字、下画线或中文字所组成。③英文字...

更可靠的Rust-语法篇-区分语句/表达式,略览if/loop/while/for

src/main.rs://函数定义fnadd(a:i32,b:i32)->i32{a+b//末尾表达式}fnmain(){leta:i3...

C++第五课:变量的命名规则_c++中变量的命名规则

变量的命名不是想怎么起就怎么起的,而是有一套固定的规则的。具体规则:1.名字要合法:变量名必须是由字母、数字或下划线组成。例如:a,a1,a_1。2.开头不能是数字。例如:可以a1,但不能起1a。3....

Rust编程-核心篇-不安全编程_rust安全性

Unsafe的必要性Rust的所有权系统和类型系统为我们提供了强大的安全保障,但在某些情况下,我们需要突破这些限制来:与C代码交互实现底层系统编程优化性能关键代码实现某些编译器无法验证的安全操作Rus...

探秘 Python 内存管理:背后的神奇机制

在编程的世界里,内存管理就如同幕后的精密操控者,确保程序的高效运行。Python作为一种广泛使用的编程语言,其内存管理机制既巧妙又复杂,为开发者们提供了便利的同时,也展现了强大的底层控制能力。一、P...