手把手带你实现一个简单的轮播图

轮播图现有成熟的插件非常多,但做为一名学习中的想要成为前端开发的小伙伴们来说,自己动手实现一个轮播图,还是很锻炼的,实现完成后,也是很有成就感的。下面,我们来实现一个简单的轮播图吧。

目录

1 HTML + CSS3布局

2 为什么要多放一个图片?

3 滚动实现

3.1 初始化变量

3.2 初始化页面元素

3.3 3秒自动滚动一次

3.4 点击按钮到达目标图片


1 HTML + CSS3布局

轮播图中,HTML布局有那么几个重要点:

  1. 外层的div元素,要设定要宽高,并且overflow:hidden;意思就是轮播图,其实是几张图片横排起来的,会非常长,所以需要将提前设定好的宽高以外的内容限制住。不能超出这个范围,超出就得让用户看不见。不过前端嘛,经常干这种事,怎么把元素隐藏起来。其实是有的,但不能让用户看见。
  2. 里层有一个div元素(或者其他ul元素也行),重点就是装这些横排起来的非常多的图片元素,这个里层的div元素呢,是可以很长的。外层的父元素已经overflow:hidden了,放心,多余的是看不见的。
  3. 让这些图片元素横排起来。不过轮播图嘛,有可点击的,有不可点击的。这一小节,我们先来实现一个纯图片的,不可点击的。什么是可点击的?你看那些正经网站,谁纯展示一个轮播图啊,那么大那么重要的区域,肯定是得诱导用户去点击你这个非常有价值的轮播图啊。
<div id="box-t">
	<div class="box-imgs" id="boxImgs" style="left:0;">
		<img class="tup" src="../images/1.jpg" alt="" />
		<img class="tup" src="../images/2.jpg" alt="" />
		<img class="tup" src="../images/3.jpg" alt="" />
		<img class="tup" src="../images/4.jpg" alt="" />
		<img class="tup" src="../images/5.jpg" alt="" />
		<img class="tup" src="../images/1.jpg" alt="" />
	</div>
    		
    <div class="box-t-y">
        <p class="box-t-x" index="1" onclick="handleBtns(0)"></p>
        <p class="box-t-x" index="2" onclick="handleBtns(1)"></p>
        <p class="box-t-x" index="3" onclick="handleBtns(2)"></p>
        <p class="box-t-x" index="4" onclick="handleBtns(3)"></p>
        <p class="box-t-x" index="5" onclick="handleBtns(4)"></p>
    </div>
</div>
#box-t{
	overflow: hidden;
	position: relative;   /*设置相对定位*/
	height: 400px;
}
.box-imgs {
	position: absolute;
	left: 0;
	top: 0;
	display: flex;
	width: 6000px;
	height: 400px;
}
#box-t img{
	width:1000px;
	height:400px;
}
.tup{
	display:block;
}
.box-t-y{
	position:absolute;  /*给按钮添加绝对定位*/
    right:45%;
    bottom:0;     /*下边距为0*/
}
.box-t-x{
    width:20px;
    height:20px;
    display: inline-block;  /*不独占一行的块级元素*/
    opacity:0.7;           /*设置透明度*/
    border:1px solid #fff;  /*边框为1像素白色实线*/
    border-radius:10px;     /*实现椭圆效果*/
    margin-right:10px;
    cursor: pointer;
}
.box-t-x:hover, .box-t-x-hover {
	background: #FC9;
}

2 为什么要多放一个图片?

本来轮播图组件中是5张图片轮播的,为什么要多放一张,看HTML元素里是6张图片元素呢?

 这是因为第5张图片播放完了以后,其实该播放第一张图片了。但如果只有5张图片的话,什么时候播放第一张图片,这需要一个时机。第5张播放完了,按理说应该继续并且顺序的播放第一张,但第一张如果在最左边的话,直接跳动到第一张,或者滚动很长,从第5张到第1张,怎么弄都很不好看。

这个时候,放第6张图片,而第6张图片存放的就是第一张图片。这样让轮播图组件顺滑的从第5张滚动到第6张,但用户看来,这其实是顺滑的滚动到了第一张图片上。当轮播图滚动到了第6张图片后,因为有3秒的等待期,这个时候,再悄么声的把图片换为第一张,用户其实是无感知的。

3 滚动实现

3.1 初始化变量

let intervalTimer = null; // 初始化定义滚动定时
let scrollIndex = 0;
let boxImgs = document.getElementById('boxImgs');
let btns = document.querySelectorAll('.box-t-x');

滚动,比如几秒滚动一次,比如每次滚动需要多久的时间,比如电脑刷新频率是一秒多少次才能不显得卡,这些都需要一定的定时任务来完成。

然后既然是轮播,那么一定随时需要知道当前滚动到第几张了,下面的按钮是第一个当前需要高亮显示。这些变量都做一个初始化。

3.2 初始化页面元素

// 初始化页面元素
function initImgs() {
   scrollIndex = 0;
   boxImgs.style.left = `0`;
   btns.forEach((item) => {
      item.className = 'box-t-x';
   })
   btns[0].className = 'box-t-x box-t-x-hover';
}
initImgs();

说是轮播图在滚动,其实是子div距离左边的距离,一直在发生变化。而且父元素已经使用了overflow:hidden。这样一来,不管是左边超出,或者是右边超出,用户都是看不到的。但这个长长的元素已经超出去了。

那么我们初始化的时候呢,设定这个子div距离左边的距离为0,意思就是初始化的时候,默认是第一张图片显示,而且图片的宽度和最外层div的宽度保持一致,这样一张图就能占满整个区域了,用户看见的就是一张图一个区域。

然后我们给底部按钮初始化一下,给第1个按钮加个选中样式,让用户知道,当前是第一张。

3.3 3秒自动滚动一次

// 3秒自动滚动
function autoScroll() {
   intervalTimer = setInterval(() => {
      let onecIndex = 1;
      let onecScroll = setInterval(() => {
         boxImgs.style.left = `-${(scrollIndex*1000) + 100*onecIndex}px`;
         if (onecIndex >= 10) {
            window.clearInterval(onecScroll);
            onecScroll = null;

            // 一次移动结束后
            scrollIndex++;
            if (scrollIndex >= 5) {
               initImgs();
            } else {
               // 底部按钮选中改变
               btns.forEach((item) => {
                  item.className = 'box-t-x';
               })
               btns[scrollIndex].className = 'box-t-x box-t-x-hover';
            }
         }
         onecIndex++;
      }, 50)

   }, 3000)
}
autoScroll();

这里采用了3秒自动滚动一次的方式,我们让之前初始化的变量scrollIndex自动累加,当要超出图片长度的时候,再将这个值恢复为0。

3.4 点击按钮到达目标图片

function handleBtns(index) {
   // 如果是点击当前的,那么无效
   if (index === scrollIndex) {
      return;
   }
   // 停止自动滚动
   window.clearInterval(intervalTimer);
   intervalTimer = null;
   // 给选中按钮加样式
   btns.forEach((item) => {
      item.className = 'box-t-x';
   })
   btns[index].className = 'box-t-x box-t-x-hover';


   let boxImgsLeft = Number(boxImgs.style.left.slice(0, -2));
   let toLeft = -index*1000;
   let scrollLeftAbs = Math.abs(toLeft - boxImgsLeft);
   // 需要频繁移动的次数
   let scrollNum = scrollLeftAbs/100;

   let onecIndex = 1;
   let onecScroll = setInterval(() => {
      // 向左滚动
      if (index > scrollIndex) {
         let newLeft = boxImgsLeft - 100*onecIndex;
         boxImgs.style.left = `${newLeft}px`;
      }
      // 向右滚动
      if (index < scrollIndex) {
         let newLeft = boxImgsLeft + 100*onecIndex;
         boxImgs.style.left = `${newLeft}px`;
      }
      if (onecIndex >= scrollNum) {
         scrollIndex = index;
         window.clearInterval(onecScroll);
         onecScroll = null;

         autoScroll();
      }
      onecIndex++;
   }, 50)
}

当点击按钮的时候,我们需要做如下判断:

  1. 如果点中的按钮和当前图片是同一张,那么就是无效的;
  2. 如果点中的按钮索引呢,比当前图片的索引大,索引是啥?就是当前是第几张,从0开始算。如果点中的索引大,那么就让轮播图继续向左滑动;
  3. 如果点中的按钮索引值,比当前图片索引值小,那么我们就让他向反方向滑动。

  • 35
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

经海路大白狗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值