JS原生实现轮播图

轮播图

主要思想就是:

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

然后通过更改列表样式里的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>

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66

这是完整的样式

在这里插入图片描述

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

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

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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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)
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

/由于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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

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';
})

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

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

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

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

文章来源: blog.csdn.net,作者:IsPinocchio,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/Pinoochio/article/details/115035379

(完)