原生js图片轮播效果实现代码


Posted in Javascript onOctober 19, 2016

现在很多javascript的插件都可以实现图片轮播的功能,这篇文章,主要是通过这个domo来解析javascript图片轮播的原理。
老规矩,先上代码。至于代码中的图片,随便找三张即可,最核心的还是理解其思想。

html:

<!DOCTYPE html> 
<html> 
 <head> 
 <meta charset="utf-8" /> 
 <title>滚动图</title> 
 <link rel="stylesheet" type="text/css" href="css/scroll.css"/> 
 </head> 
 <body> 
 <div id="wrapper"> 
  <div id="box"> 
  <img src="img/banner0.png"/> 
  <img src="img/banner1.png"/> 
  <img src="img/banner2.png"/> 
  </div> 
  <div id="pointer"> 
  <span class="active"></span> 
  <span></span> 
  <span></span> 
  </div> 
 </div> 
 <script src="js/scroll.js" type="text/javascript" charset="utf-8"></script> 
 </body> 
</html>

css:

*{ 
 margin: 0; 
 padding: 0; 
} 
#wrapper{ 
 position: relative; 
 width: 1200px; 
 margin: 50px auto; 
 overflow: hidden; 
} 
#pointer{ 
 clear: both; 
 position: absolute; 
 right: 500px; 
 bottom: 15px; 
 width: 180px; 
 height: 2px; 
} 
#pointer span{ 
 display: block; 
 box-sizing: border-box; 
 float: left; 
 width: 50px; 
 height: 1.5px; 
 margin-right: 10px; 
 border-radius: .5px; 
 background: #fff; 
 opacity: .5; 
 -webkit-opacity: .5; 
 -moz-opacity: .5; 
 filter:alpha(opacity=50); 
} 
#pointer .active{ 
 opacity: .8; 
 -webkit-opacity: .8; 
 -moz-opacity: .8; 
 filter:alpha(opacity=80); 
} 
#box{ 
 position: relative; 
 width: 3600px; 
 clear: both; 
} 
img{ 
 display: block; 
 float: left; 
 width: 1200px; 
 height: 337px; 
}

javascript:

window.onload = function(){ 
 //获取装图片的盒子 
 var box = document.getElementById('box'); 
 //获取装页码的盒子 
 var pointer = document.getElementById('pointer'); 
 //获取盒子中的所有图片 
 var imglist = box.getElementsByTagName('img') 
 //获取盒子中的所有页码 
 var pointerList = pointer.getElementsByTagName('span'); 
 //图片的宽度,正负用于左右的循环 
 var n = -1200; 
 //增加一倍的图片用于循环 
 box.innerHTML = box.innerHTML+box.innerHTML; 
 //设置盒子的宽 
 box.style.width = imglist[0].offsetWidth*imglist.length+"px"; 
 var timer = null; 
 timer = setInterval(function(){ 
 scroll(box,n,pointerList); 
 },3000); 
 box.onmouseover = function(){ 
 clearInterval(timer); 
 } 
 pointer.onmouseover = function(){ 
 clearInterval(timer); 
 } 
 box.onmouseout = function(){ 
 timer = setInterval(function (){ 
//  console.log(new Date()); 
  scroll(box,n,pointerList); 
 },3000); 
 } 
 //设置页码的点击事件 
 for(var i=0;i<pointerList.length;i++){ 
 pointerList[i].index=i;//设置一个参数,用下面调用某个页码 
 //如果不设置参数,在调用页码的时候会直接调用最后一个,因为我们使用了循环 
 pointerList[i].onclick=function (){ 
  for(var j=0;j<pointerList.length;j++){ 
  pointerList[j].className='';//清空激活的class 
  } 
  move(box,n*(this.index));//移动图片 
  this.className='active';//激活点击的页码 
 } 
 } 
 
} 
/** 
 * 循环滚动函数 
 * @param {Object} box 
 * @param {Object} n 
 */ 
function scroll(box,n,page){ 
 //判断是否到达临界点,即box的中间部分 
 if(box.offsetLeft<=-box.offsetWidth/2){ 
 box.style.left = "0px";//重新从头开始 
 console.log('0'); 
 } 
 if(box.offsetLeft%n!=0){ 
 //因为在我们切换浏览器标签页或者切换去其他软件界面的时候, 
 //会影响到setInterval,有时候setInterval会增加好几秒,在这里我们必须加一个判断 
 //只有当它走完了一个整个的图片宽度时,我们才进行下一次滚动。 
 } 
 else{ 
 pageScroll(box,n,page); 
 move(box,n+box.offsetLeft); 
 } 
} 
/** 
 * 滚动页码函数 
 * @param {Object} box 
 * @param {Object} n 
 * @param {Object} page 
 */ 
function pageScroll(box,n,page){ 
 //直接通过图片盒子的定位判断页码值,但是此时的页码值是滚动之前的,所以后面的值要+1使用 
 var index = Math.abs(box.offsetLeft/n); 
 console.log(index); 
 for(var i=0;i<page.length;i++){ 
 page[i].className=''; 
 } 
 //判断是不是最后一页,是最后一页的话+1要变成0; 
 if(index<page.length-1){ 
 page[index+1].className='active'; 
 } 
 else{ 
 page[0].className='active'; 
 } 
} 
 
/** 
 * 变速移动 
 * @param {Object} ele 
 * @param {Object} target 
 */ 
function move(ele,target){ 
 clearInterval(ele.timer); 
 console.log(new Date()); 
 ele.timer = setInterval(function () { 
 var step = (target-ele.offsetLeft)/10; 
 step = step>0?Math.ceil(step):Math.floor(step); 
 if(target==ele.offsetLeft){ 
  console.log(new Date()); 
  clearInterval(ele.timer); 
 } 
 else{ 
  ele.style.left = ele.offsetLeft + step + "px"; 
 } 
 },30); 
}

html和css部分依旧比较简单,直接跳过。javascript部分的代码注释写的也比较详细,下面主要讲解逻辑部分。
图片滚动的原理是利用setInterval函数进行背景图片的不断循环。为了避免图片循环的过程中出现间断,首先是在javascript中进行图片的复制(增加一倍),然后当到达临界点时,瞬间将图片移动到初始的位置,然后开始下一轮循环。
在这个domo中,主要包含四个函数:

1、外层控制间隔时间的函数。这个比较容易理解,通过setInterval函数每隔几秒循环执行一次图片滚动的函数。
2、中间层滚动函数。判断图片盒子是否到达临界点,判断当前状态是否符合进入下一次滚动(这个条件主要是为了防止切换界面对setInterval函数的影响,具体原因在最后)。
3、中间层页码滚动函数。基本没有难点,主要是理解页码为什么+1即可。
4、图片滚动函数。这个在之前写过的一篇文章有详细讲解,不再赘述,参考:https://3water.com/article/95211.htm

最后,一点关于setInterval底层机制的扩展。

我们内层函数的执行事件正常情况下为1-2s(测试过),而外层的循环需要3s才进行一次,正常的情况是没有问题的。但是,当你切换界面的时候,浏览器就会对setInterval函数产生影响,此时执行事件的事件就会超过3面,在没移动结束的情况下开启另一个定时器进行下一次图片滚动,所以就会发生错乱。

javascript是单线程的,当你使用setInterval函数的时候并不是真正暂停,而是先挂起这个事件,继续执行下面的事件,而当这个事件要执行时,如果浏览器当前没有任务,那么它会立马执行,但是如果浏览器有任务,那么就会有一定的延迟,这也是为什么切换界面会对setInterval函数的时间产生影响。

(关于setInterval函数的理解如有错误,欢迎指正!如果大家想要深入理解,也可以去一些大神的博客看一下setInterval函数的文章)

精彩专题分享:jQuery图片轮播 JavaScript图片轮播 Bootstrap图片轮播

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript 拾碎[三] 使用className属性
Oct 16 Javascript
JavaScript中的私有/静态属性介绍
Jul 26 Javascript
基于JavaScript 数据类型之Boolean类型分析介绍
Apr 19 Javascript
Javascript中的Array数组对象详谈
Mar 03 Javascript
使用jQuery实现的掷色子游戏动画效果
Mar 14 Javascript
JS基于Mootools实现的个性菜单效果代码
Oct 21 Javascript
jQuery实现优雅的弹窗效果(6)
Feb 08 Javascript
Bootstrap Tree View简单而优雅的树结构组件实例解析
Jun 15 Javascript
微信小程序多列选择器range-key使用详解
Mar 30 Javascript
bootstrap datetimepicker控件位置异常的解决方法
Nov 23 Javascript
前端axios下载excel文件(二进制)的处理方法
Jul 31 Javascript
微信小程序学习笔记之跳转页面、传递参数获得数据操作图文详解
Mar 28 Javascript
Angular2表单自定义验证器的实现
Oct 19 #Javascript
javascript滚轮控制模拟滚动条
Oct 19 #Javascript
Vue.js绑定HTML class数组语法错误的原因分析
Oct 19 #Javascript
微信小程序 教程之wxapp视图容器 swiper
Oct 19 #Javascript
微信小程序 教程之wxapp视图容器 scroll-view
Oct 19 #Javascript
微信小程序 教程之wxapp 视图容器 view
Oct 19 #Javascript
jQuery插件ajaxFileUpload使用实例解析
Oct 19 #Javascript
You might like
一个用php3编写的简单计数器
2006/10/09 PHP
php daddslashes()和 saddslashes()有哪些区别分析
2012/10/26 PHP
php用户注册信息验证正则表达式
2015/11/12 PHP
使用Codeigniter重写insert的方法(推荐)
2017/03/23 PHP
PHP 实现 WebSocket 协议原理与应用详解
2020/04/22 PHP
在JavaScript中遭遇级联表达式陷阱
2007/03/08 Javascript
基于jQuery的简单的列表导航菜单
2011/03/02 Javascript
AngularJS操作键值对象类似java的hashmap(填坑小结)
2016/11/12 Javascript
vue-router 权限控制的示例代码
2017/09/21 Javascript
浅谈vue引入css,less遇到的坑和解决方法
2018/01/20 Javascript
Element Input组件分析小结
2018/10/11 Javascript
[03:07]DOTA2英雄基础教程 冰霜诅咒极寒幽魂
2013/12/06 DOTA
简单理解Python中基于生成器的状态机
2015/04/13 Python
Python编程django实现同一个ip十分钟内只能注册一次
2017/11/03 Python
python 按照固定长度分割字符串的方法小结
2018/04/30 Python
Python实现串口通信(pyserial)过程解析
2019/09/25 Python
Python 图像对比度增强的几种方法(小结)
2019/09/25 Python
Python实现使用dir获取类的方法列表
2019/12/24 Python
python2 对excel表格操作完整示例
2020/02/23 Python
在keras里面实现计算f1-score的代码
2020/06/15 Python
基于Python 的语音重采样函数解析
2020/07/06 Python
python实现图书馆抢座(自动预约)功能的示例代码
2020/09/29 Python
AmazeUI 折叠面板的实现代码
2020/08/17 HTML / CSS
墨尔本照明批发商店:Mica Lighting
2017/12/28 全球购物
德国内衣、泳装和睡衣网上商店:Bigsize Dessous
2018/07/09 全球购物
美国在线购物频道:Shop LC
2019/04/21 全球购物
Rentalcars.com中国:世界上最大的在线汽车租赁服务
2019/08/22 全球购物
个人简历的自荐信
2013/10/23 职场文书
内勤主管岗位职责
2014/04/03 职场文书
捐助倡议书范文
2014/04/15 职场文书
公证委托书
2014/08/01 职场文书
世界环境日活动总结
2015/02/11 职场文书
乡镇法制宣传日活动总结
2015/05/05 职场文书
经典祝酒词大全
2015/08/12 职场文书
react国际化react-intl的使用
2021/05/06 Javascript
JavaScript实现简单的音乐播放器
2022/08/14 Javascript