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


Posted in Javascript onMarch 23, 2021

轮播图

主要思想就是:

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

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

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

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

通过给容器设定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>

这是完整的样式

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

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

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

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 相关文章推荐
从jQuery.camelCase()学习string.replace() 函数学习
Sep 13 Javascript
基于jquery的9行js轻松实现tab控件示例
Oct 12 Javascript
JS按字节截取字符长度实例
Nov 20 Javascript
关于js数组去重的问题小结
Jan 24 Javascript
javascript闭包传参和事件的循环绑定示例探讨
Apr 17 Javascript
jQuery垂直多级导航菜单代码分享
Aug 18 Javascript
javascript中alert()与console.log()的区别
Aug 26 Javascript
jQuery之动画ajax事件(实例讲解)
Jul 18 jQuery
解决ie img标签内存泄漏的问题
Oct 13 Javascript
对Vue table 动态表格td可编辑的方法详解
Aug 28 Javascript
Vue.js实现可排序的表格组件功能示例
Feb 19 Javascript
layer弹出层自定义提交取消按钮的例子
Sep 10 Javascript
几款主流好用的富文本编辑器(所见即所得常用编辑器)介绍
vue+flask实现视频合成功能(拖拽上传)
Mar 04 #Vue.js
React服务端渲染原理解析与实践
Mar 04 #Javascript
vue打开新窗口并实现传参的图文实例
Mar 04 #Vue.js
Vue-router编程式导航的两种实现代码
Mar 04 #Vue.js
手写Vue2.0 数据劫持的示例
Mar 04 #Vue.js
vue3.0封装轮播图组件的步骤
Mar 04 #Vue.js
You might like
雄兵连三大错觉:凯莎没了,凉冰阵亡了,华烨觉得自己又行了
2020/04/09 国漫
中国广播史趣谈 — 几个历史第一次
2021/03/01 无线电
PHP文件锁定写入实例解析
2014/07/14 PHP
php处理带有中文URL的方法
2016/07/11 PHP
PHP支付宝当面付2.0代码
2018/12/21 PHP
jQuery 数据缓存data(name, value)详解及实现
2010/01/04 Javascript
nodejs 后缀名判断限制代码
2011/03/31 NodeJs
jquery事件机制扩展插件 jquery鼠标右键事件。
2011/12/26 Javascript
jquery下拉select控件操作方法分享(jquery操作select)
2014/03/25 Javascript
js动态修改表格行colspan列跨度的方法
2015/03/30 Javascript
JavaScript事件详细讲解
2016/06/27 Javascript
Bootstrap3制作搜索框样式的方法
2016/07/11 Javascript
使用JS实现图片展示瀑布流效果的实例代码
2016/09/12 Javascript
Angular.Js中过滤器filter与自定义过滤器filter实例详解
2017/05/08 Javascript
jquery Form轻松实现文件上传
2017/05/24 jQuery
ionic2屏幕适配实现适配手机、平板等设备的示例代码
2017/08/11 Javascript
Webpack 服务器端代码打包的示例代码
2017/09/19 Javascript
Vue自定义弹窗指令的实现代码
2018/08/13 Javascript
用node.js写一个jenkins发版脚本
2019/05/21 Javascript
windows实现npm和cnpm安装步骤
2019/10/24 Javascript
vuex存储复杂参数(如对象数组等)刷新数据丢失的解决方法
2019/11/05 Javascript
微信小程序在text文本实现多种字体样式
2019/11/08 Javascript
微信小程序如何实现点击图片放大功能
2020/01/21 Javascript
js获取本日、本周、本月的时间代码
2020/02/01 Javascript
JS操作Fckeditor的一些常用方法(获取、插入等)
2020/02/19 Javascript
jquery实现简单自动轮播图效果
2020/07/29 jQuery
Python字典中的值为列表或字典的构造实例
2019/12/16 Python
py-charm延长试用期限实例
2019/12/22 Python
工程师必须了解的LRU缓存淘汰算法以及python实现过程
2020/10/15 Python
运动会广播稿80字
2014/01/23 职场文书
开业庆典策划方案
2014/02/18 职场文书
房产销售独家委托书范本
2014/10/01 职场文书
运动会加油稿50字
2015/07/21 职场文书
JavaScript实现淘宝商品图切换效果
2021/04/29 Javascript
Java 超详细讲解设计模式之中的抽象工厂模式
2022/03/25 Java/Android
Elasticsearch 批量操作
2022/04/19 Python