原生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 相关文章推荐
用js实现多域名不同文件的调用方法
Jan 12 Javascript
jQuery为iframe的body添加click事件的实现代码
Apr 07 Javascript
jquery validate在ie8下的bug解决方法
Nov 13 Javascript
JS判断不能为空实例代码
Nov 26 Javascript
jQuery对Select的操作大集合(收藏)
Dec 28 Javascript
jquery实现文本框数量加减功能的例子分享
May 10 Javascript
Javascript中引用类型传递的知识点小结
Mar 06 Javascript
深入理解JavaScript创建对象的多种方式以及优缺点
Jun 01 Javascript
Bootstrap输入框组件使用详解
Jun 09 Javascript
JS实现快速比较两个字符串中包含有相同数字的方法
Sep 11 Javascript
页面点击小红心js实现代码
May 26 Javascript
JavaScript使用Math.random()生成简单的验证码
Jan 21 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
PHP计划任务、定时执行任务的实现代码
2011/04/23 PHP
PHP在获取指定目录下的目录,在获取的目录下面再创建文件,多平台
2011/08/03 PHP
真正根据utf8编码的规律来进行截取字符串的函数(utf8版sub_str )
2012/10/24 PHP
php查找任何页面上的所有链接的方法
2013/12/03 PHP
ThinkPHP中url隐藏入口文件后接收alipay传值的方法
2014/12/09 PHP
Symfony2安装的方法(2种方法)
2016/02/04 PHP
Jquery 类网页微信二维码图块滚动效果具体实现
2013/10/14 Javascript
分享12个非常实用的JavaScript小技巧
2016/05/11 Javascript
手机Web APP如何实现分享多平台功能
2016/08/19 Javascript
Angular4 中内置指令的基本用法
2017/07/31 Javascript
JS获取指定月份的天数两种实现方法
2018/06/22 Javascript
JavaScript实现京东购物放大镜和选项卡效果的方法分析
2018/07/05 Javascript
微信小程序实现弹出菜单
2018/07/19 Javascript
探索JavaScript中私有成员的相关知识
2019/06/13 Javascript
详解将微信小程序接口Promise化并使用async函数
2019/08/05 Javascript
JavaScript基于SVG的图片切换效果实例代码
2020/12/15 Javascript
[03:43]2014DOTA2西雅图国际邀请赛 newbee战队巡礼
2014/07/07 DOTA
使用Python3中的gettext模块翻译Python源码以支持多语言
2015/03/31 Python
操作Windows注册表的简单的Python程序制作教程
2015/04/07 Python
python 实现删除文件或文件夹实例详解
2016/12/04 Python
Python实现将MySQL数据库表中的数据导出生成csv格式文件的方法
2018/01/11 Python
python与sqlite3实现解密chrome cookie实例代码
2018/01/20 Python
python实现excel读写数据
2021/03/02 Python
Python用5行代码写一个自定义简单二维码
2018/10/21 Python
在python下使用tensorflow判断是否存在文件夹的实例
2019/06/10 Python
python tornado使用流生成图片的例子
2019/11/18 Python
使用Python脚本从文件读取数据代码实例
2020/01/19 Python
Python集成开发工具Pycharm的安装和使用详解
2020/03/18 Python
Python django框架 web端视频加密的实例详解
2020/11/20 Python
css3过渡_动力节点Java学院整理
2017/07/11 HTML / CSS
CSS3常用的几种颜色渐变模式总结
2016/11/18 HTML / CSS
JBL加拿大官方商店:扬声器、耳机等
2020/10/23 全球购物
EJB timer的种类
2014/10/28 面试题
任课老师推荐信范文
2013/11/24 职场文书
大学新生军训自我鉴定
2014/03/18 职场文书
党员承诺书格式范文
2015/04/28 职场文书