作为一个PHP全栈攻城狮,不仅要会后端PHP和数据库,还要会前端JS。今天源码时代
PHP培训
学科老师要和大家分享一下JS原生编写轮播图的插件。 说起轮播图,很多人会选择使用各种插件,比如基于JQuery或其它框架的。不瞒大家,我也用过,甚至还用过Flash的轮播图。总体来说,用起来是比较简单,但是有一个非常严重的问题,那就是加载速度非常非常慢。
如果能自己使用JS原生写一个轮播图,不仅速度快,那感觉也是高大上,颇有高级前端工程师的feel啊。不过今天为了大家好理解,我们使用面向过程的代码编写(面向过程关注细节,方便理解原理;面向对象使用方便,但不方便新手理解)。
在开始编写之前我们需要准备几张测试图片,以及一些技术基础:JavaScript、HTML、CSS。为了方便测试,我们约定一下测试环境:三张相同大小的图片放在images目录中,所有的JS、HTML、CSS代码写在一个html文件中;由于使用了新的DOM API,所以建议使用chrome50以上版本的浏览器。
编写思路:
1)来三张图和三个按钮,将所有图片排成一行,将第一张复制一份放在最后(也可以全部复制放在后面,但只会用到第一张,重复出现一次三张图,一共六张图)
2)通过外边距偏移实现轮播
默认显示第1张图
第1次改变,第1张图移出,第2张图出现
第2次改变,第2张图移出,第3张图出现
第0次改变,第3张图移出,第4张图出现(第4张是第1张的复制,用户感觉是回到了第1张)
轮回,第0次改变,瞬间将移回第1张,由于第4张图和第1张一样,所以用户无法感觉这个变化,然后继续第1张图移出,第2张出现
...
3)给按钮添加点击事件
触发时停止自动播放,并切换到指定的图片
第一步:编写HTML和CSS
编写HTML:
三张图
三个按钮
编写CSS:
将所有图片排成一行
将按钮排到轮播图中间底部
设置按钮的状态样式
代码如下:
复制代码
第二步:编写JavaScript获取元素
获取轮播图片总数(用于计算显示轮回)
获取每屏宽度(用于计算每次偏移量)
代码:
复制代码
第三步:实现轮播
设置定时器实现隔3秒切换一张图片
切换图片时,需要传入切换到指定图片的编号
计算偏移量
设置定时器实现偏移时的动画效果
实现按钮状态同步变化
JS代码:
复制代码
第四步:按钮功能
给所有按钮添加事件
点击时停止自动播放,切换到指定的图片
JS代码:
复制代码
代码汇总:
复制代码
如果能自己使用JS原生写一个轮播图,不仅速度快,那感觉也是高大上,颇有高级前端工程师的feel啊。不过今天为了大家好理解,我们使用面向过程的代码编写(面向过程关注细节,方便理解原理;面向对象使用方便,但不方便新手理解)。
在开始编写之前我们需要准备几张测试图片,以及一些技术基础:JavaScript、HTML、CSS。为了方便测试,我们约定一下测试环境:三张相同大小的图片放在images目录中,所有的JS、HTML、CSS代码写在一个html文件中;由于使用了新的DOM API,所以建议使用chrome50以上版本的浏览器。
编写思路:
1)来三张图和三个按钮,将所有图片排成一行,将第一张复制一份放在最后(也可以全部复制放在后面,但只会用到第一张,重复出现一次三张图,一共六张图)
2)通过外边距偏移实现轮播
默认显示第1张图
第1次改变,第1张图移出,第2张图出现
第2次改变,第2张图移出,第3张图出现
第0次改变,第3张图移出,第4张图出现(第4张是第1张的复制,用户感觉是回到了第1张)
轮回,第0次改变,瞬间将移回第1张,由于第4张图和第1张一样,所以用户无法感觉这个变化,然后继续第1张图移出,第2张出现
...
3)给按钮添加点击事件
触发时停止自动播放,并切换到指定的图片
第一步:编写HTML和CSS
编写HTML:
三张图
三个按钮
编写CSS:
将所有图片排成一行
将按钮排到轮播图中间底部
设置按钮的状态样式
代码如下:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>轮播图1</title>
- <style>
- .banner{overflow:hidden;position:relative;border:4px solid #f00;width:1000px;}
- .banner ul{margin:0;padding:0;list-style:none;}
- .banner .list li{float:left;}
- .banner .list img{display:block;width:100%;}
-
- .icos{position:absolute;z-index:1;left:50%;bottom:14px;}
- .icos li{text-indent:-9999px;background:#ccc;width:12px;height:12px;float:left;margin:0 5px;border-radius:100%;}
- .icos li.on{background:#f00;}
- </style>
- </head>
- <body>
- <div class="banner">
- <ul class="list">
- <li><img src="images/01.jpg"></li>
- <li><img src="images/02.jpg"></li>
- <li><img src="images/03.jpg"></li>
- </ul>
- <ul class="icos">
- <li class="on">0</li>
- <li>1</li>
- <li>2</li>
- </ul>
- </div>
- </body>
- </html>
获取轮播图片总数(用于计算显示轮回)
获取每屏宽度(用于计算每次偏移量)
代码:
- <script>
- window.onload=function(){
- //获取所有元素
- var list=document.querySelector('.list');
- var icos=document.querySelectorAll('.icos li');
- var li=document.querySelectorAll('.list li');
- var len=li.length; //一共几张图
- var li_width=document.querySelector('.banner').clientWidth; //每张图的宽度
- list.innerHTML=list.innerHTML+list.innerHTML; //在列表最后添加一份,在展示最后一张切到第一张时实际展示的是刚添加的这张
- li=document.querySelectorAll('.list li'); //重新获取所有节点
- //为每一个li设置宽度
- for(var i=0;i<li.length;i++){
- li[i].style.width=li_width+'px';
- }
- list.style.width=li_width*li.length+"px"; //设置总宽度,让所有图片在一行显示
- }
- </script>
第三步:实现轮播
设置定时器实现隔3秒切换一张图片
切换图片时,需要传入切换到指定图片的编号
计算偏移量
设置定时器实现偏移时的动画效果
实现按钮状态同步变化
JS代码:
- //通过偏移实现动画
- function show(n){
- if(n==1){ //这个判断顺序很关键,必须放在上面,实现最后一张瞬间切回第一张,再转到第二张
- list.style.marginLeft='0px';
- }
- /*
- 默认出现第1张
- n=1 动画出现第二张,第一张消失
- n=2 动画出现第三张,第二张消失
- n=0 动画出现第四张(第一张的复制),第三张消失
- n=1 瞬间切回第一张(由于第一张和第四张相同,肉眼看不出变化),再动画出现第二张,第一张消失
- */
-
- var w=n>0 ? -(n-1)*li_width : -(len-1)*li_width; //计算偏移量,以实现动画效果,等于0时特殊处理,展示手动加的那一张
- var step=20; //步长可根据宽度计算得到
- var i=step;
- var timer=setInterval(function(){
- list.style.marginLeft=(w-i)+'px';
- i+=step;
- if(i>li_width){ //显示完一张图就停止
- clearInterval(timer);
- }
- },20);
-
- //改变按钮状态
- for(var j=0; j<icos.length; j++){
- if(n==j){
- icos[j].className='on';
- }else{
- icos[j].className='';
- }
- }
- }
-
- //自动播放函数
- function autoplay(){
- var count=1; //初始是第1张,自动播放从第2张开始
- timeId=setInterval(function(){
- show(count % len); //取余数实现轮流播放
- count++;
- },3000);
- }
-
- autoplay();
给所有按钮添加事件
点击时停止自动播放,切换到指定的图片
JS代码:
- //给每一个按钮绑定事件
- for(var i=0; i<icos.length; i++){
- icos[i].onmouseover=function(){ //鼠标移到小图标上时取消自动播放并切换到指定的图片上
- clearInterval(timeId);
- show(this.innerText);
- }
- icos[i].onmouseout=function(){ //鼠标移开时继续自动播放
- autoplay();
- }
- }
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title>轮播图1</title>
- <style>
- .banner{overflow:hidden;position:relative;border:4px solid #f00;width:1000px;}
- .banner ul{margin:0;padding:0;list-style:none;}
- .banner .list li{float:left;}
- .banner .list img{display:block;width:100%;}
-
- .icos{position:absolute;z-index:1;left:50%;bottom:14px;}
- .icos li{text-indent:-9999px;background:#ccc;width:12px;height:12px;float:left;margin:0 5px;border-radius:100%;}
- .icos li.on{background:#f00;}
- </style>
- </head>
- <body>
- <div class="banner">
- <ul class="list">
- <li><img src="images/01.jpg"></li>
- <li><img src="images/02.jpg"></li>
- <li><img src="images/03.jpg"></li>
- </ul>
- <ul class="icos">
- <li class="on">0</li>
- <li>1</li>
- <li>2</li>
- </ul>
- </div>
-
- <script>
- window.onload=function(){
- //获取所有元素
- var list=document.querySelector('.list');
- var icos=document.querySelectorAll('.icos li');
- var li=document.querySelectorAll('.list li');
- var len=li.length; //一共几张图
- var li_width=document.querySelector('.banner').clientWidth; //每张图的宽度
- list.innerHTML=list.innerHTML+list.innerHTML; //在列表最后添加一份,在展示最后一张切到第一张时实际展示的是刚添加的这张
- li=document.querySelectorAll('.list li'); //重新获取所有节点
-
- //为每一个li设置宽度
- for(var i=0;i<li.length;i++){
- li[i].style.width=li_width+'px';
- }
- list.style.width=li_width*li.length+"px"; //设置总宽度,让所有图片在一行显示
-
- //给每一个按钮绑定事件
- for(var i=0; i<icos.length; i++){
- icos[i].onmouseover=function(){ //鼠标移到小图标上时取消自动播放并切换到指定的图片上
- clearInterval(timeId);
- show(this.innerText);
- }
- icos[i].onmouseout=function(){ //鼠标移开时继续自动播放
- autoplay();
- }
- }
-
- //通过偏移实现动画
- function show(n){
- if(n==1){ //这个判断顺序很关键,必须放在上面,实现最后一张瞬间切回第一张,再转到第二张
- list.style.marginLeft='0px';
- }
- /*
- 默认出现第1张
- n=1 动画出现第二张,第一张消失
- n=2 动画出现第三张,第二张消失
- n=0 动画出现第四张(第一张的复制),第三张消失
- n=1 瞬间切回第一张(由于第一张和第四张相同,肉眼看不出变化),再动画出现第二张,第一张消失
- */
-
- var w=n>0 ? -(n-1)*li_width : -(len-1)*li_width; //计算偏移量,以实现动画效果,等于0时特殊处理,展示手动加的那一张
- var step=20; //步长可根据宽度计算得到
- var i=step;
- var timer=setInterval(function(){
- list.style.marginLeft=(w-i)+'px';
- i+=step;
- if(i>li_width){ //显示完一张图就停止
- clearInterval(timer);
- }
- },20);
-
- //改变按钮状态
- for(var j=0; j<icos.length; j++){
- if(n==j){
- icos[j].className='on';
- }else{
- icos[j].className='';
- }
- }
- }
-
- //自动播放函数
- function autoplay(){
- var count=1; //初始是第1张,自动播放从第2张开始
- timeId=setInterval(function(){
- show(count % len); //取余数实现轮流播放
- count++;
- },3000);
- }
-
- autoplay();
- }
- </script>
- </body>
- </html>
总结,和所有的PHP框架一样,所有JS框架和库都是基于原生JS编写的,只有把原生JS的代码掌握好,才能以不变应万变,在技术领域平静对待各种变化。
本文来源:http://bbs.itsource.cn/thread-1662-1-1.html,转载请注明出处!