整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

带你手写一个轮播图之HTML结构和CSS布局设计

前端项目开发中,大家可能多少都有用到过轮播图。一般为了省事,我们会使用现成的库,比如swiper。当然,很多组件库也带有轮播图组件,比如element-ui的ElCarousel组件。但是,有多少童鞋曾思考过其实现原理呢?又有多少童鞋尝试过手写一个呢?

其实,实现一个轮播图相当简单,我打算出一个大约3节的连载教程,教大家怎样一步一步实现轮播图。今天,我们先讲解结构和布局的设计。

首先,我们创建一个项目文件夹carousel-demo,在该目录下新建images文件夹和index.html,main.js,style.css三个文件。然后,大家找3张相同尺寸的banner图和2个相同尺寸的小图标放入images文件夹。我用的banner图尺寸是1280*720,文件名分别是1.jpg,2.jpg,3.jpg;我用的图标尺寸是32*32,文件名分别是left.png和right.png。

最终,我们实现的轮播图界面长这样,大家说漂不漂亮?

接下来,我们打开index.html文件,先创建一个基本的骨架,并引入我们刚才创建的css和js文件,代码如下:

<!DOCTYPE html>
<html lang="zh-CN">
<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>Carousel demo</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <script src="main.js"></script>
</body>
</html>

我们的轮播图需要一个外层容器元素,该元素包含一个banner列表,一个指示器和一组左右导航按钮。由于默认显示第一张图片,所以我们给第一个指示器项添加了一个active类。代码如下:

  <div class="carousel-wrapper">
    <ul class="slides">
      <li class="slide-item">
        <img src="images/1.jpg">
      </li>
      <li class="slide-item">
        <img src="images/2.jpg">
      </li>
      <li class="slide-item">
        <img src="images/3.jpg">
      </li>
    </ul>
    <ul class="indicators">
      <li class="indicator-item active"></li>
      <li class="indicator-item"></li>
      <li class="indicator-item"></li>
    </ul>
    <ul class="nav">
      <li class="nav-left"></li>
      <li class="nav-right"></li>
    </ul>
  </div>

现在,我们打开style.css文件,首先对默认样式做一些重置,将所有元素的内外边距设为0,盒模型设为边框盒。为了去掉li元素前面的小圆点,我们将li元素的list-style设为none。样式如下:

* {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

li {
  list-style: none;
}

接下来,我们从外到内,从上到下为元素定义样式。

首先,我们定义外层容器元素的样式。为了使布局更灵活,我们先给它指定一个最大宽度,并让其在水平方向居中。由于它的子元素需要堆叠,我们给它设置相对定位,让子元素相对于它来定位。由于我们的banner列表有多张图片,可以左右滚动,每次仅一张图片可见,所以需要将不可见的图片裁掉。样式如下:

.carousel-wrapper {
  max-width: 800px;
  margin: auto;
  position: relative;
  overflow: hidden;
}

接下来,我们定义banner列表和其子元素样式。我们的banner列表有3张图片,可以左右滚动,每次仅显示一张,所以banner的宽度与容器一样,banner列表宽度是容器的3倍。

我们将banner列表元素显示为弹性盒,以让所有banner在一行排列显示。由于弹性盒子元素会均分空间,而我们的banner图宽度相同,所以不需要设置banner的宽度,仅将banner内的img元素宽度设为100%即可。

我们也为banner列表添加了过渡属性,当使用JS动态改变变换值的时候会有动画效果。样式如下:

.slides {
  width: 300%;
  display: flex;
  transition: transform .3s;
}

.slide-item img {
  display: block;
  width: 100%;
}

下面,我们定义指示器样式。我们的指示器需要在banner列表上层底部居中显示,我们使用left和X轴平移变换结合实现水平居中,全部样式如下:

.indicators {
  position: absolute;
  bottom: 10px;
  left: 50%;
  transform: translateX(-50%);
  display: flex; // 弹性盒,让子元素在一行显示
  padding: 5px;
  border-radius: 10px;
  background-color: rgba(255, 255, 255, .3);
  pointer-events: none; // 阻止指示器容器成为指针事件目标
}

.indicator-item {
  pointer-events: all; // 让指示器子元素可以成为指针事件目标
  cursor: pointer; 
  width: 30px;
  height: 6px;
  margin: 0 4px;
  border-radius: 6px;
  background-color: #999;
}

.indicator-item.active { // 为活动指示器项设置一个不同的样式
  background-color: #ccc;
}

最后,我们定义导航按钮样式。我们的导航按钮需要在banner列表上层两边垂直方向居中显示,我们使用top和Y轴平移变换结合实现垂直居中,全部样式如下:

.nav li {
  cursor: pointer;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 40px;
  height: 40px;
  background-color: rgba(255, 255, 255, .3);
  background-repeat: no-repeat;
  background-position: center;
  background-size: 24px;
}

.nav-left {
  left: 0;
  background-image: url(images/left.png);
}

.nav-right {
  right: 0;
  background-image: url(images/right.png);
}

以上就是本文的全部内容了,童鞋们都理解了吗?还有什么不懂的欢迎评论区提问,感谢阅读!

体代码如下:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<style>
			*{margin: 0;
			padding: 0;}
#box {
	width: 100%;
	height: 502px;
	overflow: hidden;/*溢出的部分:隐藏*/
}

#box .menu {
	width: 607%;
	position: relative;
	margin-left: -40px;/*左外边距*/
	bottom: 0px;/*低边距离*/

}

#box .menu ul li {
	float: left;/*浮动:左,就是要把图片往左浮动*/
	list-style: none;
}




		</style>
	</head>
	<body>
		<div id="box"><!--最外的大盒子-->
			<div class="menu"><!--这里是写入我们要播放的图片-->
				<ul><!--无序列表-->
					<li><img src="image/01.jpg" width="1546px;" height="500px"></li>
					<li><img src="image/02.jpg" width="1546px;" height="500px"></li>
                    <li><img src="image/03.jpg" width="1546px;" height="500px"></li>
                    <li><img src="image/04.jpg" width="1546px;" height="500px"></li>
                    <li><img src="image/05.jpg" width="1546px;" height="500px"></li>
                    <li><img src="image/06.jpg" width="1546px;" height="500px"></li>
				</ul>
			</div>
			
		</div>
		<!--在这里导入javascript文件也就是js代码,如果没有这个就没有动画-->
		<script src="jquery-3.4.1.min.js" type="text/javascript"></script>
		<!--写代码-->
        <script>
//      	function就是函数执行
        	$(function(){
        		//一般获取元素用var,从第一张图片开始
        		var _index=0,  
//        		 窗口宽度,就是把所有图片放在水平线上的总宽度
        		window_width=1546, 
        		//时间循环
        		timer=null,  
        		//图片内容一共六张
        		images_count=6;
        		//获取下一个
        		function nextPlay(){
        			if(_index>images_count-1){//_index指的是每一张图片
        				_index=0;//从第一张开始
        				              //stop() 停留,animate自定义动画往左运动,
        				$("#box .menu").stop().animate({left:-window_width*_index},500);
        			}else{
        				$("#box .menu").stop().animate({left:-window_width*_index},500);
        			} 
        			//每一个图片加一就是自动按顺序出来
        			_index++;
        		}
        		timer=setInterval(nextPlay,2000);
        	})
        </script>
	</body>
</html>

javascript文件也就是js文件:链接:https://pan.baidu.com/s/1_RUihF6SdA4-NJcqHGqm1g

提取码:mnfg

技术交流群里面,有人冒出来问,谁有轮播插件,因为我也没用过,但是我觉得轮播这个功能其实蛮简单的,可以自己创造,我觉得编程的乐趣就在于创造,创造出属于你的东西,编程才有了灵魂。

下面不多说,由于代码有几部分,所以图片方式进行代码演示:

首先准备一下材料:我使用的是jquery写的,所以需要准备这个插件就可以了:

主要HTML代码

解释:整个轮播会分为3部分:一个大的div,包含了图片、轮播节点、动画插入。其中轮播节点与动画展示使用绝对位置定位,使得它从流中脱离出来,具体样式如下图:

主要的样式设计

解释:轮播节点就是图片地址一样,轮到哪一张就亮哪一张。节点使用绝对位置,并设置位于第三层。

接下来就是使得它开始动起来,动起来需要使用什么方法呢?当然了有两种方法,一种是CSS3,另一种是使用计时器配合动画方法animate。CSS3这种属于纯样式设计,对于固定的来说,还是可以的,至于动态的,后期不断增加更改的,暂时没去了解过,所以下面使用定时器这种方法:

代码如下:

主要js代码

上面的代码,主要逻辑都有注释,imglabel(i)用来实时跟踪图片,跟着图片走;divanimate(i)用来每一张图片插入动画,里面的html属于变量相当于组件复用,可以往里面传入你要说的话,和其他内容。

那么整个轮播就出来,效果如下

<script src="https://lf3-cdn-tos.bytescm.com/obj/cdn-static-resource/tt_player/tt.player.js?v=20160723"></script>


创造是编程的乐趣,所以欢迎小伙伴们留言,一起讨论提提升。