web技术

JS原生实现轮播图的几种方法

2023-07-08 03:49 作者:Admin

轮播图

主要思想就是:

在大的容器里,装着一个很长的表,表是容器宽度的整数倍。

然后通过更改列表样式里的left属性来实现左右滑动。

本文旨在控制滑动五张图片,但在html中使用了七张图片,第一张和最后一张是有重复的,至于原因会在下面解释。

通过给容器设定overflow:hidden属性来保证只显示容器视口大小的一张图片。

<body>
  <div id="container">
    /*容器*/
    <div id="wrap" style="left: -400px">
      /*存放图片的列表*/
      <div class="item item5">l5</div>
      <div class="item item1">1</div>
      <div class="item item2">2</div>
      <div class="item item3">3</div>
      <div class="item item4">4</div>
      <div class="item item5">5</div>
      <div class="item item1">r1</div>
    </div>
  </div>
  <div id="key">
    /*设置按钮*/
    <div id="list">
      /*点击小圆圈切换到固定图片*/
      <div class="btn1 btnNum">1</div>
      <div class="btn2 btnNum">2</div>
      <div class="btn3 btnNum">3</div>
      <div class="btn4 btnNum">4</div>
      <div class="btn5 btnNum">5</div>
    </div>
    <div id="btn">
      /*向左切换和向右切换的按钮*/
      <button class="left">←</button>
      <button class="right">→</button>
    </div>
  </div>
</body>

CSS:

可以给wrap列表设置flex属性,让图片在一行显示。其他布局可以按自己需求来做。

注意在定义id="wrap"d的节点中设置了内联样式left。因为在切换图片的时候我用到的是left属性,而如果不设置left的话,在DOM设置style时是找不到left属性的。

<style>
#container {
	width: 400px;
	height: 300px;
	border: 8px rgb(8, 8, 8) solid;
	margin: 0 auto;
	margin-top: 150px;
	overflow: hidden;
	position: relative;
}

#wrap {
	width: 2800px;
	height: 300px;
	display: flex;
	position: relative;
}

.item {
	flex: 1;
	width: 400px;
	height: 300px;
}

.item1 {
	background-color: rosybrown;
}

.item2 {
	background-color: rgb(12, 226, 37);
}

.item3 {
	background-color: rgb(212, 221, 29);
}

.item4 {
	background-color: rgb(61, 27, 182);
}

.item5 {
	background-color: rgb(221, 23, 145);
}

#key {
	width: 400px;
	height: 300px;
	margin: 0 auto;
}

#list {
	width: 400px;
	height: 40px;
	display: flex;
	justify-content: center;
}

#list div {
	margin-top: 10px;
	margin-left: 10px;
	width: 20px;
	height: 20px;
	background-color: rgb(13, 162, 221);
	text-align: center;
	border-radius: 45%;
	opacity: 0.6;
}

#list div:hover {
	cursor: pointer;
	opacity: 1;
}

#btn {
	width: 400px;
	text-align: center;
}
</style>

这是完整的样式

每种颜色代表一张图片,且按序标了序号。起始位置是第二张图片。

至于为什么第一张和最后一张有额外重复的一张放在两端,是为了在做滑动效果的时候,最后一张(倒数第二张,粉紫色)可以继续向右顺滑的滑到第一张(其实是本图的第二张,浅棕色的)。第一张(本图第二张,浅棕色)向左滑动时可以顺滑的滑到最后一张(实则倒数第二张)。继续往下看。

1. 多种轮播方式

轮播必然离开不了定位,以及修改wrap列表的left属性,使其移动。

先初始化几个数据

var wrap = document.getElementById("wrap");
var nowleft = -400; //用于存放当前列表的left的值
var currIndex = 1; //用于存放当前是第几个图片
//定位到几个按钮
var btnNum = document.getElementsByClassName("btnNum"); //小圆圈

var right = document.getElementsByClassName("right")[0]; //向右滑的按钮
var left = document.getElementsByClassName("left")[0]; //向左滑的按钮

1.1 定时自动轮播效果

只讲向左自动滑动的效果

既然是自动轮播的,那必然少不了setInterval()定时器让其持续轮播。

function next() {
  setInterval(function () {
    //设置每两秒切换一次图片
    wrap.style.transition = "left 1s"; //设定有过渡滑动的效果
    nowleft = parseInt(wrap.style.left) - 400; //切换一次后nowleft应该减少(即向左滑)一个图片的宽度
    wrap.style.left = nowleft + "px"; //然后将nowleft赋值给wrap的left属性
    if (parseInt(wrap.style.left) == -2400) {
      //判断到最后一个后,偷偷变回到最开头的位置
      setTimeout(() => {
        wrap.style.transition = "none"; //因为是偷偷变回去,所以要取消过渡效果
        nowleft = -400;
        wrap.style.left = nowleft + "px";
      }, 1200); //保证定时器的时间大于过度的时间且小于每次轮换的时间
    }
  }, 2000);
}

/由于wrap.style.left 返回的是带px的字符串,所以用parseInt可以取得前面的数值/

1.2 按向右滑动按钮

right.addEventListener("click", function () {
  if (nowleft >= -2000) {
    //判断是否到最后一个图了,没有的话就开始滑动
    nowleft -= 400;
    wrap.style.transition = "left 1s";
    wrap.style.left = nowleft + "px";
  }
  if (nowleft == -2400) {
    //如果到最后一个图了,就偷偷换回第一张图
    setTimeout(() => {
      wrap.style.transition = "none";
      nowleft = -400;
      wrap.style.left = nowleft + "px";
    }, 1020);
  }
});

1.3 小圆圈切换图片

for (let i = 0; i < btnNum.length; i++) {
  btnNum[0].style.opacity = 1;
  btnNum[i].addEventListener("click", function () {
    wrap.style.transition = "left 1s";
    for (let j = 0; j < btnNum.length; j++) {
      btnNum[j].style.opacity = "0.6";
    }
    btnNum[i].style.opacity = 1;
    nowleft = nowleft - (i + 1 - currIndex) * 400;
    currIndex = i + 1;
    wrap.style.left = nowleft + "px";
  });
}

其实本文在控制从最后一个图偷偷换回第一张图的操作是有缺陷的,因为要把控序号5的图滑动到序号为r1的图是需要1s的,然而wrap.style.left是直接发生变化的,不会随着过渡期间发生位移而left一直变化。所以把控序号5完整滑动到r1后再偷偷切换到序号1的时间是有些难控制的。

而且比如从序号1连续点击3下是可以切换到序号4的。然是从序号5连续点击3下是不可以的,在r1切换到序号1的时候是无法响应点击效果的,因此此处交互差异会容易感到别扭。

如果想改善这个别扭的bug,可以用下防抖来改善。

标签: #轮播图 #JavaScript
推荐文章
HTML5 Canvas是一种强大的Web技术,它允许我们使用JavaScript在网页上创建和...
在这个程序中,我们将使用JavaScript创建一个可以在屏幕上放烟花的效果。我...
轮播图在网站中几乎无处不在,占用地方少,交互性好。今天就来聊聊如何用vu...
大部分网站或APP的首页差不多都运用到了轮播图,下边就探讨一下关于轮播图的...
轮播图实现思路:1、img_ul类里面存放img标签,将需要展示的图片依次排开,在...
推荐专题
如何自己建网站?建网站难不难?其实建网站说难不难,说容易也并不容易,难...
本专题精心收集整理了多种HTML+CSS+JS轮播图实现方案,带详细代码和讲解,正...