原生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 相关文章推荐
JavaScrip实现PHP print_r的数功能(三种方法)
Nov 12 Javascript
jQuery ui 利用 datepicker插件实现开始日期(minDate)和结束日期(maxDate)
May 22 Javascript
angularJS与bootstrap结合实现动态加载弹出提示内容
Oct 16 Javascript
基于jQuery实现的无刷新表格分页实例
Feb 17 Javascript
JS函数的定义与调用方法推荐
May 12 Javascript
DataTables添加额外的查询参数和删除columns等无用参数实例
Jul 04 Javascript
React Native自定义控件底部抽屉菜单的示例
Feb 08 Javascript
vue2.0 computed 计算list循环后累加值的实例
Mar 07 Javascript
vue与vue-i18n结合实现后台数据的多语言切换方法
Mar 08 Javascript
微信二次分享报错invalid signature问题及解决方法
Apr 01 Javascript
Vue开发之watch监听数组、对象、变量操作分析
Apr 25 Javascript
基于javascript的无缝滚动动画实现2
Aug 07 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数组冒泡排序算法实例
2016/05/06 PHP
PHP基于phpqrcode类生成二维码的方法示例详解
2020/08/07 PHP
求得div 下 img的src地址的js代码
2007/02/28 Javascript
javascript语言结构小记(一)
2011/09/10 Javascript
jquery默认校验规则整理
2014/03/24 Javascript
jQuery实现Twitter的自动文字补齐特效
2014/11/28 Javascript
Jquery中Event对象属性小结
2015/02/27 Javascript
浅析Node.js中使用依赖注入的相关问题及解决方法
2015/06/24 Javascript
jQuery获取checkboxlist的value值的方法
2015/09/27 Javascript
js编写贪吃蛇的小游戏
2020/08/24 Javascript
jQuery+Ajax实现用户名重名实时检测
2017/06/01 jQuery
微信小程序获取手机网络状态的方法【附源码下载】
2017/12/08 Javascript
微信、QQ、微博、Safari中使用js唤起App
2018/01/24 Javascript
详解如何实现一个简单的 vuex
2018/02/10 Javascript
Vue.js自定义事件的表单输入组件方法
2018/03/08 Javascript
[03:44]2014DOTA2国际邀请赛 71专访:DK战队赛前讨论视频遭泄露
2014/07/13 DOTA
Python random模块(获取随机数)常用方法和使用例子
2014/05/13 Python
用python与文件进行交互的方法
2018/03/01 Python
Python实现将json文件中向量写入Excel的方法
2018/03/26 Python
Python输入二维数组方法
2018/04/13 Python
使用OpenCV circle函数图像上画圆的示例代码
2019/12/27 Python
python爬虫库scrapy简单使用实例详解
2020/02/10 Python
Matplotlib使用Cursor实现UI定位的示例代码
2020/03/12 Python
css3media响应式布局实例
2016/07/08 HTML / CSS
荷兰之家英文站:Holland at Home
2016/10/26 全球购物
德购商城:德国进口直邮商城
2017/06/13 全球购物
香蕉共和国加拿大官网:Banana Republic加拿大
2018/08/06 全球购物
北大青鸟学生求职信
2013/09/24 职场文书
经济管理专业毕业生推荐信
2013/11/11 职场文书
学校法制宣传月活动总结
2014/07/03 职场文书
小学科学教学计划
2015/01/21 职场文书
教师求职自荐信范文
2015/03/04 职场文书
小兵张嘎观后感300字
2015/06/03 职场文书
导游词之河北白洋淀
2020/01/15 职场文书
Go语言空白表示符_的实例用法
2021/07/04 Golang
MongoDB支持的索引类型
2022/04/11 MongoDB