《HTML + CSS + JS 打造炫酷轮播图详解》

发布于:2025-03-13 ⋅ 阅读:(16) ⋅ 点赞:(0)

《HTML + CSS + JS 打造炫酷轮播图详解》

一、项目概述

本次项目旨在使用 HTML、CSS 和 JavaScript 实现一个具有基本功能的轮播图,包括图片自动轮播、上一张 / 下一张按钮切换、小圆点指示与切换等功能,以提升网页的交互性和视觉吸引力。

二、实现步骤

(一)图片拼接做出架构

1、HTML 结构搭建

  • 在 HTML 文件中,首先创建一个 div 容器,设置 idbanner,作为轮播图的整体框架。
  • banner 内部,创建一个无序列表 ulidlist,用于存放轮播的图片。每个图片项为 li 元素,li 内部嵌套 img 标签引入图片资源,如:
<div id="banner">
  <ul id="list">
    <li><img src="./img/p2.jpg"></li>
    <li><img src="./img/p3.jpg"></li>
    <li><img src="./img/p2 - 副本.jpg"></li>
    <li><img src="./img/p3 - 副本.jpg"></li>
    <li><img src="./img/p2.jpg"></li>
  </ul>
</div>
  • 接着创建另一个无序列表 ulidicolist,用于存放小圆点,每个小圆点为 li 元素,初始内容为数字序号,用于标识对应的图片:
<ul id="icolist">
  <li>1</li>
  <li>2</li>
  <li>3</li>
  <li>4</li>
</ul>
  • 最后,创建两个 div 元素,分别作为向前和向后的按钮,设置 idprenex,并添加相应的箭头符号作为内容:
<div class="prev" id="pre"></div>
<div class="next" id="nex"></div>

2、CSS 样式设置

  • 使用通配符选择器 * 对所有元素进行初始化,去除默认的 margin、padding 和列表样式:
* {
  margin: 0;
  padding: 0;
  list-style: none;
}
  • banner 容器设置宽度 650px、高度 250px,添加 2px 灰色边框,设置相对定位 position: relative,并隐藏超出部分 overflow: hidden,使其水平居中 margin:100px auto 0;
#banner {
  width: 650px;
  height: 250px;
  border: 2px solid #999;
  position: relative;
  overflow: hidden;
  margin:100px auto 0;
}
  • 对于图片列表 #list,设置宽度 3500px(考虑到图片数量和切换效果,确保足够宽度容纳所有图片移动),高度 250px,使其内部的 li 元素左浮动 float: left,图片宽度 700px、高度 250px 以适应容器:
#list {
  width: 3500px;
  height: 250px;
}
#list li {
  float: left;
}
#list li img {
  width: 700px;
  height: 250px;
}
  • 向前按钮 .prev 和向后按钮 .next,设置宽度 30px、高度 40px,背景色为灰色 #999,文字颜色白色 color: aliceblue,水平垂直居中 text-align: center; line-height: 40px,绝对定位在容器底部左右两侧合适位置,设置 cursor: pointer 以显示手型指针:
.prev{
  width:30px;
  height:40px;
  background-color: #999;
  color: aliceblue;
  text-align: center;
  line-height: 40px;
  position:absolute;
  bottom:45%;
  left:5px;
  cursor: pointer;
}
.next{
  width:30px;
  height:40px;
  background-color: #999;
  color: aliceblue;
  text-align: center;
  line-height: 40px;
  position:absolute;
  bottom:45%;
  right:5px;
  cursor: pointer;
}
  • 小圆点 #icolist 列表设置绝对定位在容器右下角,li 元素设置宽度 30px、高度 30px,圆形 border-radius: 50%,灰色背景 background: #999,白色文字 color: #fff,水平垂直居中,左浮动并设置一定间距 margin-left: 5px,同样设置 cursor: pointer
#icolist {
  position: absolute;
  right:10px;
  bottom: 10px;
}
#icolist li{
  width:30px;
  height:30px;
  border-radius: 50%;
  background: #999;
  color: #fff;
  text-align: center;
  line-height: 30px;
  float: left;
  margin-left: 5px;
  cursor: pointer;
}

(二)定时器实现简单轮播效果

1、在 JavaScript 代码中,首先等待页面加载完成,使用 window.onload 事件:

window.onload = function() {
  // 后续代码将写在此处
}

2、在 window.onload 函数内部,获取图片列表元素 eimglist 和用于控制轮播的变量 left(初始为 0,表示图片列表的初始偏移量),并定义定时器相关变量 timer

var eimglist = document.querySelector('#list');
var left = 0;
var timer;

3、创建run函数,用于实现图片的自动轮播逻辑:

  • 首先判断如果图片向左滚动到最后一张(即 left < -2800,因为每张图片宽度 700px,共 4 张图片循环,总偏移量为 -2800px),则将 left 重置为 0,实现循环效果:
if (left < -2800) {
  left = 0;
}
  • 计算当前显示图片的序号 m,通过 Math.floor(-left/700),取整得到当前图片是第几张:
var m = Math.floor(-left/700);
  • 处理图片滚动时的特殊情况,当图片刚好滚动完一轮(即 left % 700 == 0),设置一个较小的偏移量 n = 1200,模拟快速切换到下一轮第一张图片的效果,否则设置常规偏移量 n = 10
var n = (left % 700 == 0)? n = 1200 : n = 10;
  • 更新图片列表的 marginLeft 属性,实现图片向左移动:
left -= 10;
list.style.marginLeft = left + 'px'
  • 使用 setTimeout 递归调用 run 函数,实现定时轮播,间隔时间为 n 毫秒:
timer = setTimeout(run,n);

(三)做出上一张下一张按钮

(此时 banner 中 overflow:hidden 需要先注释掉,要不然看不到那两个按钮),此时这个要做决定定位,并给他们添加点击事件)

1、在 CSS 中,由于按钮默认被 overflow:hidden 隐藏,暂时注释掉 banner 容器的 overflow:hidden 属性,以便能看到按钮并调整位置:

/* #banner {
  overflow: hidden;
} */

2、在 JavaScript 中,获取向前按钮 prev_btn 和向后按钮 next_btn

var prev_btn = document.getElementById('pre');
var next_btn = document.getElementById('nex');

3、给向前按钮添加点击事件处理函数:

  • 计算当前图片的上一张图片序号 prevgo,通过 Math.floor(-left/700)+1,并处理边界情况,当 prevgo == 0(即已经是第一张图片,点击上一张应切换到最后一张),将 prevgo 设置为 3:
prev_btn.onclick = function() {
  let prevgo = Math.floor(-left/700)+1;
  if(prevgo == 0) {
    prevgo = 3;
  }
  // 后续调用图片定位函数
}

4、给向后按钮添加点击事件处理函数:

  • 类似地,计算当前图片的下一张图片序号 nextgo,通过 Math.floor(-left/700)+1,并处理边界情况,当 nextgo == 4(即已经是最后一张图片,点击下一张应切换到第一张),将 nextgo 设置为 0:
next_btn.onclick = function() {
  let nextgo = Math.floor(-left/700)+1;
  if(nextgo == 4) {
    nextgo = 0;
  }
  // 后续调用图片定位函数
}

(四)实现上一张下一张代码

我们做一个 imgchange() 图片定位函数

1、在 JavaScript 中,创建imgchange函数:

  • 函数接收一个参数 n,表示要切换到的图片序号,根据序号计算图片列表需要的偏移量 lt,通过 -(n*700),并更新图片列表的 marginLeft 属性,同时更新全局变量 left
function imgchange(n) {
  let lt = -(n*700);
  list.style.marginLeft = lt + 'px';
  left = lt;
}

2、在向前按钮和向后按钮的点击事件处理函数中,分别调用 imgchange 函数传入计算好的 prevgonextgo

prev_btn.onclick = function() {
  let prevgo = Math.floor(-left/700)+1;
  if(prevgo == 0) {
    prevgo = 3;
  }
  imgchange(prevgo);
}
next_btn.onclick = function() {
  let nextgo = Math.floor(-left/700)+1;
  if(nextgo == 4) {
    nextgo = 0;
  }
  imgchange(nextgo);
}

(五)做出轮播图上的四个小圆点

1、在 HTML 结构中的 #icolist 列表已经创建了四个 li 元素作为小圆点,初始内容为数字 1 - 4,用于标识图片序号。

2、在 CSS 样式中,已经对 #icolist 及其内部 li 元素进行了样式设置,使其呈现为圆形、灰色背景、白色文字并在轮播图右下角合理排列,且鼠标悬停时有手型指针效果。

(六)小圆点跟着图片滚动变红,做一个 icochange() 圆点跟随函数

1、在 JavaScript 中,创建icochange函数:

  • 首先使用 for 循环遍历所有小圆点 esico(通过 document.getElementById('icolist').getElementsByTagName('li') 获取),将它们的背景色清空:
function icochange(m) {
  for(let index = 0; index < esico.length; index++) {
    esico[index].style.backgroundColor = '';
  }
  • 然后根据传入的当前图片序号 m,判断如果 m 小于小圆点数量 esico.length,将对应序号的小圆点背景色设置为红色:
if(m < esico.length) {
  esico[m].style.backgroundColor = 'red';
}
}

2、在 run 函数中,每次图片切换时调用 icochange 函数传入当前图片序号 m,实现小圆点跟随图片变色:

function run() {
  // 其他代码...
  icochange(m);
  // 其他代码...
}

(七)点击小圆点切图,完成最终效果

1、在 JavaScript 中,给小圆点列表eicolist

添加点击事件处理函数:

  • 获取点击的目标元素 tg,通过 event.target,并从目标元素的 innerHTML 中获取点击的小圆点序号 ico,注意要减 1 以匹配图片序号(因为小圆点内容从 1 开始,而图片序号从 0 开始):
eicolist.onclick = function () {
  var tg = event.target;
  var ico = tg.innerHTML - 1;
  // 后续调用图片定位和小圆点变色函数
}

2、在点击事件处理函数中,分别调用 imgchange 函数传入 ico 实现图片切换,调用 icochange 函数传入 ico 实现对应小圆点变色:

eicolist.onclick = function () {
  var tg = event.target;
  var ico = tg.innerHTML - 1;
  imgchange(ico);
  icochange(ico);
}

3、最后,为了优化用户体验,当鼠标悬停在图片列表上时,停止轮播,移开后继续轮播:

  • 给图片列表 eimglist 添加 onmouseover 事件处理函数,在其中使用 clearTimeout 停止定时器:
eimglist.onmouseover = function() {
  clearTimeout(timer);
}
  • 给图片列表 eimglist 添加 onmouseout 事件处理函数,在其中调用 run 函数重新启动轮播:
eimglist.onmouseout = function() {
  run();
}

三、全部代码

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style type="text/css">
			* {
				margin: 0;
				padding: 0;
				list-style: none;
			}

			#banner {
				width: 650px;
				height: 250px;
				border: 2px solid #999;
				position: relative;
				overflow: hidden;
				margin:100px auto 0;
			}
			
			/* 轮播图列表图片 */
			#list {
				width: 3500px;
				height: 250px;
			}

			#list li {
				float: left;
			}

			#list li img {
				width: 700px;
				height: 250px;
			}
			
			/* 向前的按钮 */
			.prev{
				width:30px;
				height:40px;
				background-color: #999;
				color: aliceblue;
				text-align: center;
				line-height: 40px;
				position:absolute;
				bottom:45%;
				left:5px;
				cursor: pointer;
			}
			/* 向后按钮 */
			.next{
				width:30px;
				height:40px;
				background-color: #999;
				color: aliceblue;
				text-align: center;
				line-height: 40px;
				position:absolute;
				bottom:45%;
				right:5px;
				cursor: pointer;
			}
			
			/* 小圆点 */
			#icolist{
				position: absolute;
				right:10px;
				bottom: 10px;
			}
			
			#icolist li{
				width:30px;
				height:30px;
				border-radius: 50%;
				background: #999;
				color: #fff;
				text-align: center;
				line-height: 30px;
				float: left;
				margin-left: 5px;
				cursor: pointer;
			}
		</style>
		<script>
			window.onload = function() {
				var prev_btn=document.getElementById('pre')
				var next_btn=document.getElementById('nex')
				// 获取小圆点的li标签
				var esico=document.getElementById('icolist').getElementsByTagName('li');
				var eicolist=document.querySelector('#icolist');
				// 获取图片列表元素
				var eimglist=document.querySelector('#list');
				var left = 0;
				var timer;
				run()
                
				function run() {
					// 如果滚动完,重新开始
					if (left < -2800) {
						left = 0;
					}
					// 常见变量m获取当前图片序号
					var m=Math.floor(-left/700);
					
					// 此时轮播图尾部有一张空白,我们需要补接第一张才不会有空,我们添加一张图片,修改图片列表宽度
					var n = (left % 700== 0) ? n = 1200 : n = 10;
					left -= 10;
					list.style.marginLeft = left + 'px'
					timer = setTimeout(run,n);
					// 调用icochange进行小圆点变化
					icochange(m);
				}
				
				// 我们做一个图片定位函数
				function imgchange(n){
					let lt=-(n*700);
					list.style.marginLeft=lt+'px';
					left=lt;
				}
				
				    prev_btn.onclick=function(){
					let prevgo=Math.floor(-left/700)+1;
					if(prevgo==0){
						prevgo=3;
					}
					imgchange(prevgo)
				}
				next_btn.onclick=function(){
					let nextgo=Math.floor(-left/700)+1;
					if(nextgo==4){
						nextgo=0;
					}
					imgchange(nextgo)
				}
				
				// icochange()圆点跟随函数
				function icochange(m){
					// 通过for循环所有li元素背景色清空
					for(let index=0;index<esico.length;index++){
						esico[index].style.backgroundColor='';
					}
					// 当图片所在的小圆点设置背景色为红色
					if(m<esico.length){
						esico[m].style.backgroundColor='red';
					}
				}
				
				// 创建列表元素点击事件
				eicolist.onclick=function (){
					// tg获取事件目标元素
					var tg=event.target;
					// 通过ico获取点击的序号
					var ico=tg.innerHTML-1;
					imgchange(ico);
					icochange(ico);
				}
				// 鼠标在图片列表上时轮播停止,移开后又启动
				eimglist.onmouseover=function(){
					clearTimeout(timer);
				}
				eimglist.onmouseout=function(){
					run();
				}
			}
		</script>
	</head>
	<body>
		<div id="banner">
			<ul id="list">
				<li><img src="./img/p2.jpg"></li>
				<li><img src="./img/p3.jpg"></li>
				<li><img src="./img/p2 - 副本.jpg"></li>
				<li><img src="./img/p3 - 副本.jpg"></li>
				<li><img src="./img/p2.jpg"></li>
			</ul>
			
			<!-- 小圆点 -->
			<ul id="icolist">
				<li>1</li>
				<li>2</li>
				<li>3</li>
				<li>4</li>
			</ul>
			<!-- 向前向后按钮 -->
			<div class="prev" id="pre"></div>
			<div class="next" id="nex"></div>
		</div>
	</body>
</html>

四、总结

通过以上步骤,逐步构建了一个完整的轮播图功能。从最初的 HTML 结构搭建,到 CSS 样式美化,再到 JavaScript 实现复杂的交互逻辑,包括定时器控制自动轮播、按钮点击切换、小圆点指示与交互等。在实现过程中,需要注意变量的管理、边界情况的处理以及元素的样式和定位协调,以确保轮播图的流畅运行和良好展示效果。同时,这种实现方式也为进一步扩展轮播图功能,如添加动画效果、响应式设计等提供了基础。