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 相关文章推荐
Javascript中Eval函数的使用说明
Oct 11 Javascript
细说浏览器特性检测(2)-通用事件检测
Nov 05 Javascript
基于JQuery实现CheckBox全选全不选
Jun 27 Javascript
Java 正则表达式学习总结和一些小例子
Sep 13 Javascript
javascript继承机制实例详解
Nov 20 Javascript
基于Css3和JQuery实现打字机效果
Aug 11 Javascript
jQuery Easyui 验证两次密码输入是否相等
May 13 Javascript
Javascript实现图片加载从模糊到清晰显示的方法
Jun 21 Javascript
将form表单通过ajax实现无刷新提交的简单实例
Oct 12 Javascript
浅谈实现vue2.0响应式的基本思路
Feb 13 Javascript
vue获取当前激活路由的方法
Mar 17 Javascript
Layer.js实现表格溢出内容省略号显示,悬停显示全部的方法
Sep 16 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
基于curl数据采集之单页面采集函数get_html的使用
2013/04/28 PHP
浅析HTTP消息头网页缓存控制以及header常用指令介绍
2013/06/28 PHP
Windows下Apache + PHP SESSION丢失的解决过程全纪录
2015/04/07 PHP
jQuery入门第一课 jQuery选择符
2010/03/14 Javascript
jQuery源码分析-04 选择器-Sizzle-工作原理分析
2011/11/14 Javascript
简单漂亮的js弹窗可自由拖拽且兼容大部分浏览器
2013/10/22 Javascript
为jQuery添加Webkit的触摸的方法分享
2014/02/02 Javascript
JS显示下拉列表框内全部元素的方法
2015/03/31 Javascript
jQuery实现html元素拖拽
2015/07/21 Javascript
浅析nodejs实现Websocket的数据接收与发送
2015/11/19 NodeJs
JS判断图片是否加载完成方法汇总(最新版)
2016/05/13 Javascript
使用伪命名空间封装保护独自创建的对象方法
2016/08/04 Javascript
javascript阻止事件冒泡和浏览器的默认行为
2017/01/21 Javascript
深入理解React Native原生模块与JS模块通信的几种方式
2017/07/24 Javascript
解决vue处理axios post请求传参的问题
2018/03/05 Javascript
JS实现json对象数组按对象属性排序操作示例
2018/05/18 Javascript
利用hasOwnProperty给数组去重的面试题分享
2018/11/05 Javascript
点击按钮弹出模态框的一系列操作代码实例
2019/03/29 Javascript
详细分析vue表单数据的绑定
2020/07/20 Javascript
python爬虫爬取快手视频多线程下载功能
2018/02/28 Python
Python使用 Beanstalkd 做异步任务处理的方法
2018/04/24 Python
python实现顺时针打印矩阵
2019/03/02 Python
Puppeteer使用示例详解
2019/06/20 Python
Python内存管理实例分析
2019/07/10 Python
Python 列表去重去除空字符的例子
2019/07/20 Python
基于django传递数据到后端的例子
2019/08/16 Python
python读取多层嵌套文件夹中的文件实例
2020/02/27 Python
Django怎么在admin后台注册数据库表
2020/11/14 Python
在pycharm中使用pipenv创建虚拟环境和安装django的详细教程
2020/11/30 Python
加拿大女鞋品牌:ALDO
2016/11/13 全球购物
Ted Baker美国官网:英国时尚品牌
2018/10/29 全球购物
农贸市场管理制度
2014/01/31 职场文书
医药销售求职信范文
2014/02/01 职场文书
初三开学计划书
2014/04/27 职场文书
班子查摆四风个人对照检查材料思想汇报
2014/10/04 职场文书
Python的这些库,你知道多少?
2021/06/09 Python