原生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 相关文章推荐
基于jquery的blockui插件显示弹出层
Apr 14 Javascript
angularJS提交表单(form)
Feb 09 Javascript
jquery实现下拉框功能效果【实例代码】
May 06 Javascript
jQuery中借助deferred来请求及判断AJAX加载的实例讲解
May 24 Javascript
详解Angular开发中的登陆与身份验证
Jul 27 Javascript
vue.js2.0点击获取自己的属性和jquery方法
Feb 23 jQuery
js技巧之十几行的代码实现vue.watch代码
Jun 09 Javascript
jquery判断滚动条距离顶部的距离方法
Sep 05 jQuery
详解js动态获取浏览器或页面等容器的宽高
Mar 13 Javascript
基于Fixed定位的框选功能的实现代码
May 13 Javascript
JS计算斐波拉切代码实例
Sep 12 Javascript
vue+elementui实现点击table中的单元格触发事件--弹框
Jul 18 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
安装apache2.2.22配置php5.4(具体操作步骤)
2013/06/26 PHP
php基于base64解码图片与加密图片还原实例
2014/11/03 PHP
php实现简单文件下载的方法
2015/01/30 PHP
javascript 强制刷新页面的实现代码
2009/12/13 Javascript
网站404页面3秒后跳到首页的实例代码
2013/08/16 Javascript
Javascript解析URL方法详解
2014/12/05 Javascript
学习JavaScript编程语言的8张思维导图分享
2015/03/27 Javascript
JS 拦截全局ajax请求实例解析
2016/11/29 Javascript
12 款 JS 代码测试必备工具(翻译)
2016/12/13 Javascript
Jquery Easyui菜单组件Menu使用详解(15)
2016/12/18 Javascript
ionic+AngularJs实现获取验证码倒计时按钮
2017/04/22 Javascript
vue2.x+webpack快速搭建前端项目框架详解
2017/11/30 Javascript
jQuery滚动条美化插件nicescroll简单用法示例
2018/04/18 jQuery
jQuery实现经典的网页3D轮播图封装功能【附源码下载】
2019/02/15 jQuery
node-red File读取好保存实例讲解
2019/09/11 Javascript
解决Vue的文本编辑器 vue-quill-editor 小图标样式排布错乱问题
2020/08/03 Javascript
django传值给模板, 再用JS接收并进行操作的实例
2018/05/28 Python
python笔记之mean()函数实现求取均值的功能代码
2019/07/05 Python
Matplotlib scatter绘制散点图的方法实现
2020/01/02 Python
python对execl 处理操作代码
2020/06/22 Python
python获取本周、上周、本月、上月及本季的时间代码实例
2020/09/08 Python
基于Python爬取素材网站音频文件
2020/10/21 Python
pycharm 实现调试窗口恢复
2021/02/05 Python
PyCharm 光标变成黑块的解决方式
2021/02/06 Python
CSS3弹性布局内容对齐(justify-content)属性使用详解
2017/07/31 HTML / CSS
通过CSS3的object-fit来调整图片适配尺寸的技巧简介
2016/02/27 HTML / CSS
马来西亚网上花店:FlowerAdvisor马来西亚
2020/01/03 全球购物
儿科护理实习自我鉴定
2013/09/19 职场文书
医院总经理岗位职责
2014/02/04 职场文书
酒店总经理助理职责
2014/02/12 职场文书
十一酒店活动方案
2014/02/20 职场文书
学校地质灾害防治方案
2014/06/10 职场文书
公务员中国梦演讲稿
2014/08/19 职场文书
小学生五年级大队长竞选发言稿
2014/09/12 职场文书
四风问题个人对照检查材料
2014/09/26 职场文书
父亲婚礼答谢词
2015/01/04 职场文书