轮播图 原生js实现

你的名字 2022-03-22 11:46 468阅读 0赞

原生js实现轮播图

 很多网站上都有轮播图,但却很难找到一个系统讲解的,因此这里做一个简单的介绍,希望大家都能有所收获,如果有哪些不正确的地方,希望大家可以指出。

 github地址 (如果有用,就star一下吧)

 

原理:

  将一些图片在一行中平铺,然后计算偏移量再利用定时器实现定时轮播。

步骤一:建立html基本布局

如下所示:

复制代码

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>轮播图</title>
  6. </head>
  7. <body>
  8. <div class="container">
  9. <div class="wrap" style="left:-600px;">
  10. <img src="./img/5.jpg" alt="">
  11. <img src="./img/1.jpg" alt="">
  12. <img src="./img/2.jpg" alt="">
  13. <img src="./img/3.jpg" alt="">
  14. <img src="./img/4.jpg" alt="">
  15. <img src="./img/5.jpg" alt="">
  16. <img src="./img/1.jpg" alt="">
  17. </div>
  18. <div class="buttons">
  19. <span>1</span>
  20. <span>2</span>
  21. <span>3</span>
  22. <span>4</span>
  23. <span>5</span>
  24. </div>
  25. <a href="javascript:;" class="arrow arrow_left"><</a>
  26. <a href="javascript:;" class="arrow arrow_right">></a>
  27. </div>
  28. </body>
  29. </html>

复制代码

   只有五张图片,却使用7张来轮播,这是为了实现无缝轮播,后面会详细介绍。

  而5个span,即我们可以实时看到轮播图目前所处的位置。

  最后是两个按钮,可以通过它来控制前进与后退。

  这里我们需要对wrap使用绝对定位,所以用left:-600px;将第一张图片显示出来。

步骤二: css布局

  首先,resetcss,如下所示:

复制代码

  1. * {
  2. margin:0;
  3. padding:0;
  4. }
  5. a{
  6. text-decoration: none;
  7. }

复制代码

  接着,我们为了让图片只在container中,所以需要限定其宽度和高度并且使用overflow:hidden;将其余的图片隐藏起来,并且我们希望wrap相对于container左右移动,所以设置为relative,如下:

复制代码

  1. .container {
  2. position: relative;
  3. width: 600px;
  4. height: 400px;
  5. margin:100px auto 0 auto;
  6. box-shadow: 0 0 5px green;
  7. overflow: hidden;
  8. }

复制代码

  我们设置wrap是绝对定位的,所以,我们就可以通过控制Left和Right来控制图片的移动了。设置z-index:1;以对后面将要放置的buttons作为参考。 因为共有七张图片,所以width为4200px(每张图片我们设置为600X400),我们只需让图片左浮动即可实现占满一排了。

  1. .wrap {
  2. position: absolute;
  3. width: 4200px;
  4. height: 400px;
  5. z-index: 1;
  6. }

  然后我们把图片设置位左浮动,并限定其大小,如下所示:

  1. .container .wrap img {
  2. float: left;
  3. width: 600px;
  4. height: 400px;
  5. }

  现在的效果如下:

  1. ![1044137-20170219160953519-1844848679.png][]

  即这时已经显示出了第一张图片。并且充满了整个container(container是有box-shadow的);

  然后我们把显示次序的buttons放在图片的右下角。并且设置z-index:2;以保证buttons是在图片的上面的。

复制代码

  1. .container .buttons {
  2. position: absolute;
  3. right: 150px;
  4. bottom:20px;
  5. width: 100px;
  6. height: 10px;
  7. z-index: 2;
  8. }

复制代码

  然后将buttons下面的span做一个简单的修饰,并且给和图片对应的span设置一个on类,如下:

复制代码

  1. .container .buttons span {
  2. margin-left: 5px;
  3. display: inline-block;
  4. width: 20px;
  5. height: 20px;
  6. border-radius: 50%;
  7. background-color: green;
  8. text-align: center;
  9. color:white;
  10. cursor: pointer;
  11. }
  12. .container .buttons span.on{
  13. background-color: red;
  14. }

复制代码

  接下来,我们把左右切换的箭头加上,然后做简单的修饰,注意:因为这里使用实体来表示左右箭头,所以设置font-size才能改变其大小,

复制代码

  1. .container .arrow {
  2. position: absolute;
  3. top: 35%;
  4. color: green;
  5. padding:0px 14px;
  6. border-radius: 50%;
  7. font-size: 50px;
  8. z-index: 2;
  9. display: none;
  10. }
  11. .container .arrow_left {
  12. left: 10px;
  13. }
  14. .container .arrow_right {
  15. right: 10px;
  16. }
  17. .container:hover .arrow {
  18. display: block;
  19. }
  20. .container .arrow:hover {
  21. background-color: rgba(0,0,0,0.2);
  22. }

复制代码

  

   

步骤三:添加js逻辑

  我们首先获取到 wrap(因为要设置其left才能控制轮播图),然后获取到左右两个箭头,并实现手动轮播,如下:

复制代码

  1. var wrap = document.querySelector(".wrap");
  2. var next = document.querySelector(".arrow_right");
  3. var prev = document.querySelector(".arrow_left");
  4. next.onclick = function () {
  5. next_pic();
  6. }
  7. prev.onclick = function () {
  8. prev_pic();
  9. }
  10. function next_pic () {
  11. var newLeft = parseInt(wrap.style.left)-600;
  12. wrap.style.left = newLeft + "px";
  13. }
  14. function prev_pic () {
  15. var newLeft = parseInt(wrap.style.left)+600;
  16. wrap.style.left = newLeft + "px";
  17. }

复制代码

  值得注意的是,这里wrap.style.left是一个字符串,所以要转化为数字才能进行计算,而设定left时就要加上px成为一个字符串了。

  现在我们来测试一下:

1044137-20170219165527519-501714242.gif

  可以看到,在第一页时,left值为-600,所以我们可以点击一次上一张,但是当再点击一次时,就出现了空白。同样的,下一张点击,到-3600是最后一张,就不能再继续点击了。  

  也就是说,当我们点击下一张到-3600px(这是第一张图片)时,我们需要下次跳转到第二张,即-1200px;这样才能正常跳转;

  同理,当我们点击上一张到0px(这是第五张图片时),我们希望下次跳转到第四张,即-2400px;

  按照这样的思路我们重新将next_pic和prev_pic函数修改如下:

复制代码

  1. function next_pic () {
  2. var newLeft;
  3. if(wrap.style.left === "-3600px"){
  4. newLeft = -1200;
  5. }else{
  6. newLeft = parseInt(wrap.style.left)-600;
  7. }
  8. wrap.style.left = newLeft + "px";
  9. }
  10. function prev_pic () {
  11. var newLeft;
  12. if(wrap.style.left === "0px"){
  13. newLeft = -2400;
  14. }else{
  15. newLeft = parseInt(wrap.style.left)+600;
  16. }
  17. wrap.style.left = newLeft + "px";
  18. }

复制代码

  这时,我们就可以发现图片可以循环播放了!

  但是,这时我们仅仅时手动循环播放的,我们如果希望自动播放,使用setInterval()即可,如下所示:

复制代码

  1. var timer = null;
  2. function autoPlay () {
  3. timer = setInterval(function () {
  4. next_pic();
  5. },1000);
  6. }
  7. autoPlay();

复制代码

  即先设定一个计时器,然后创建一个可以自动播放的函数,最后调用这个函数即可。 现在它就可以自动播放了,效果如下:

  1044137-20170219172144957-1060270822.gif

  但是如果我们想要仔细看其中一个图片的时候,我们希望轮播图停止播放,只要clearInterval()即可,如下:

复制代码

  1. var container = document.querySelector(".container");
  2. container.onmouseenter = function () {
  3. clearInterval(timer);
  4. }
  5. container.onmouseleave = function () {
  6. autoPlay();
  7. }

复制代码

  现在,只要我们把鼠标移入轮播图中,这时轮播图就不会播放了。而移开鼠标之后,轮播图自动播放。

  但是到目前为止,轮播图下方的小圆点还没有动,现在我们就实现它。

  原理很简单,即设置buttons的index初始值为0,即第一个span的class为on,然后触发next_pic函数时,index加1,当触发prev_pic函数时,inex减1, 并设置当前index的小圆点的class为on, 这就要求index必须设置为全局变量,才能保证它在每一个函数的作用域中。

  添加showCurrentDot函数:

复制代码

  1. var index = 0;
  2. var dots = document.getElementsByTagName("span");
  3. function showCurrentDot () {
  4. for(var i = 0, len = dots.length; i < len; i++){
  5. dots[i].className = "";
  6. }
  7. dots[index].className = "on";
  8. }

复制代码

  在next_pic中添加代码:

  1. index++;
  2. if(index > 4){
  3. index = 0;
  4. }

  在prev_pic中添加大吗:

  1. index--;
  2. if(index < 0){
  3. index = 4;
  4. }
  5. showCurrentDot();

  这样,轮播图就可以自动切换,并且小圆点也在随着图片的变化而变化了。

  但是,这距离我们经常看到的轮播图还有一定距离 - - - 当点击小圆点时, 就可跳转到相应图片。 实现原理即: 点击小圆点,就使wrap的Left变成相应的值。代码如下:

复制代码

  1. for (var i = 0, len = dots.length; i < len; i++){
  2. (function(i){
  3. dots[i].onclick = function () {
  4. var dis = index - i;
  5. if(index == 4 && parseInt(wrap.style.left)!==-3000){
  6. dis = dis - 5;
  7. }
  8. //和使用prev和next相同,在最开始的照片5和最终的照片1在使用时会出现问题,导致符号和位数的出错,做相应地处理即可
  9. if(index == 0 && parseInt(wrap.style.left)!== -600){
  10. dis = 5 + dis;
  11. }
  12. wrap.style.left = (parseInt(wrap.style.left) + dis * 600)+"px";
  13. index = i;
  14. showCurrentDot();
  15. }
  16. })(i);
  17. }

复制代码

  原理就是当点击到小圆点时,得到相应的i值,这个i值也就是span的index值,我们拿他和全局变量index作比较,然后重新设置wrap.style.left的值,然后把i值复制给全局变量index,最后显示当前的小原点即可。值得注意的是:这里涉及到了闭包的概念,如果直接使用for循环,则不能得到正确的结果。

  最终效果如图:

 1044137-20170219202408379-302681457.gif

  最终代码如下所示:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>轮播图</title>
  6. <style>
  7. * {
  8. margin:0;
  9. padding:0;
  10. }
  11. a{
  12. text-decoration: none;
  13. }
  14. .container {
  15. position: relative;
  16. width: 600px;
  17. height: 400px;
  18. margin:100px auto 0 auto;
  19. box-shadow: 0 0 5px green;
  20. overflow: hidden;
  21. }
  22. .container .wrap {
  23. position: absolute;
  24. width: 4200px;
  25. height: 400px;
  26. z-index: 1;
  27. }
  28. .container .wrap img {
  29. float: left;
  30. width: 600px;
  31. height: 400px;
  32. }
  33. .container .buttons {
  34. position: absolute;
  35. right: 5px;
  36. bottom:40px;
  37. width: 150px;
  38. height: 10px;
  39. z-index: 2;
  40. }
  41. .container .buttons span {
  42. margin-left: 5px;
  43. display: inline-block;
  44. width: 20px;
  45. height: 20px;
  46. border-radius: 50%;
  47. background-color: green;
  48. text-align: center;
  49. color:white;
  50. cursor: pointer;
  51. }
  52. .container .buttons span.on{
  53. background-color: red;
  54. }
  55. .container .arrow {
  56. position: absolute;
  57. top: 35%;
  58. color: green;
  59. padding:0px 14px;
  60. border-radius: 50%;
  61. font-size: 50px;
  62. z-index: 2;
  63. display: none;
  64. }
  65. .container .arrow_left {
  66. left: 10px;
  67. }
  68. .container .arrow_right {
  69. right: 10px;
  70. }
  71. .container:hover .arrow {
  72. display: block;
  73. }
  74. .container .arrow:hover {
  75. background-color: rgba(0,0,0,0.2);
  76. }
  77. </style>
  78. </head>
  79. <body>
  80. <div class="container">
  81. <div class="wrap" style="left: -600px;">
  82. <img src="./img/5.jpg" alt="">
  83. <img src="./img/1.jpg" alt="">
  84. <img src="./img/2.jpg" alt="">
  85. <img src="./img/3.jpg" alt="">
  86. <img src="./img/4.jpg" alt="">
  87. <img src="./img/5.jpg" alt="">
  88. <img src="./img/1.jpg" alt="">
  89. </div>
  90. <div class="buttons">
  91. <span class="on">1</span>
  92. <span>2</span>
  93. <span>3</span>
  94. <span>4</span>
  95. <span>5</span>
  96. </div>
  97. <a href="javascript:;" class="arrow arrow_left"><</a>
  98. <a href="javascript:;" class="arrow arrow_right">></a>
  99. </div>
  100. <script>
  101. var wrap = document.querySelector(".wrap");
  102. var next = document.querySelector(".arrow_right");
  103. var prev = document.querySelector(".arrow_left");
  104. next.onclick = function () {
  105. next_pic();
  106. }
  107. prev.onclick = function () {
  108. prev_pic();
  109. }
  110. function next_pic () {
  111. index++;
  112. if(index > 4){
  113. index = 0;
  114. }
  115. showCurrentDot();
  116. var newLeft;
  117. if(wrap.style.left === "-3600px"){
  118. newLeft = -1200;
  119. }else{
  120. newLeft = parseInt(wrap.style.left)-600;
  121. }
  122. wrap.style.left = newLeft + "px";
  123. }
  124. function prev_pic () {
  125. index--;
  126. if(index < 0){
  127. index = 4;
  128. }
  129. showCurrentDot();
  130. var newLeft;
  131. if(wrap.style.left === "0px"){
  132. newLeft = -2400;
  133. }else{
  134. newLeft = parseInt(wrap.style.left)+600;
  135. }
  136. wrap.style.left = newLeft + "px";
  137. }
  138. var timer = null;
  139. function autoPlay () {
  140. timer = setInterval(function () {
  141. next_pic();
  142. },2000);
  143. }
  144. autoPlay();
  145. var container = document.querySelector(".container");
  146. container.onmouseenter = function () {
  147. clearInterval(timer);
  148. }
  149. container.onmouseleave = function () {
  150. autoPlay();
  151. }
  152. var index = 0;
  153. var dots = document.getElementsByTagName("span");
  154. function showCurrentDot () {
  155. for(var i = 0, len = dots.length; i < len; i++){
  156. dots[i].className = "";
  157. }
  158. dots[index].className = "on";
  159. }
  160. for (var i = 0, len = dots.length; i < len; i++){
  161. (function(i){
  162. dots[i].onclick = function () {
  163. var dis = index - i;
  164. if(index == 4 && parseInt(wrap.style.left)!==-3000){
  165. dis = dis - 5;
  166. }
  167. //和使用prev和next相同,在最开始的照片5和最终的照片1在使用时会出现问题,导致符号和位数的出错,做相应地处理即可
  168. if(index == 0 && parseInt(wrap.style.left)!== -600){
  169. dis = 5 + dis;
  170. }
  171. wrap.style.left = (parseInt(wrap.style.left) + dis * 600)+"px";
  172. index = i;
  173. showCurrentDot();
  174. }
  175. })(i);
  176. }
  177. </script>
  178. </body>
  179. </html>

  

总结:

  实现一个轮播图还是不难的,大体思路: 先创建一个div,限定其宽度和高度,overflow:hidden,且设置其position为relative。然后创建一个装图片的div,宽度为所有图片的总宽度,且设置其position为absolute,并且使其中的内容浮动,这样所有的图片就处于一行中。然后为了实现无缝滚动,所以需要在首尾分别添加一张过渡图片。 先添加两个按钮, 使其可以手动轮播,然后只需要添加一个定时器使其朝一个方向自动轮播即可,因为用户有时需要查看详情,所以当鼠标进入时就clear定时器,滑出再定时播放。为了更好地用户体验,我们再下面添加了一排小圆点,用户可以清楚地知道现在所处的位置, 最后, 利用闭包使得用户可以直接通过点击小圆点切换图片。

发表评论

表情:
评论列表 (有 0 条评论,468人围观)

还没有评论,来说两句吧...

相关阅读

    相关 原生js实现

            很多很多网站经常会用到一个特效,那就是轮播图,对于日新月异的前端技术来说其实就是一个框架一个接口的事,但轮播的原理是什么?用最原始的javascript来写又是

    相关 原生js实现

    轮播图基本上是前端所必须面临的一个功能。而且在网上可以找到各种各样的插件或者写法。 但是我个人觉得还是写一下比较好。这里用到的是原生JS、CSS3相结合的写法。 对IE 8

    相关 原生js实现

    原生js实现轮播图  很多网站上都有轮播图,但却很难找到一个系统讲解的,因此这里做一个简单的介绍,希望大家都能有所收获,如果有哪些不正确的地方,希望大家可以指出。  [