视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
原生JS实现图片无缝滚动方法(附带封装的运动框架)
2020-11-27 22:28:22 责编:小采
文档

话说轮播图效果是前端er学习JS的必经之路啊,很多同学写的第一个JS效果应该就是它了,在各大网站我们都会经常见到,但是无缝滚动运动效果的轮播图,对于小白们来说还是有一定难度的。

我们来看看思路吧~

首先我们要实现的效果有以下几点:

小圆点:点击小圆点显示与之对应的图片

向左和向右按钮:点击向左按钮图片向后运动,点击向右按钮图片向前运动

定时器:每隔 2s 自动播放

主要难点在于:

当图片运动到最后一张,点击向右的按钮时,应该显示第一张;

当前显示的是第一张,点击向左的按钮时,应该显示最后一张;

思路:

1、先将第一张图片复制 添加到 ul 最后面,将最后一张图片复制 添加到 ul 最前面(此时 ul 的第一张图片是pic3,最后一张图片是pic0);

2、当图片(ul)运动到pic3,继续向前运动,运动到最后一张pic0时,瞬间把 ul 拉回到第二张图片pic0的位置,然后在继续向前运动;

3、当图片(ul)向后运动到第一张图片pic3时,瞬间把 ul 拉回到倒数第二张图片pic3的位置。

4、还有非常关键的一点:定义iNow变量,用于对应当前显示的图片与ol中的小圆点,并且可以用来关联 ul 的位置。

html代码:

<div id="tab">
 <ul>
 <li><img src="image/pic0.jpg" alt="" /></li>
 <li><img src="image/pic1.jpg" alt="" /></li>
 <li><img src="image/pic2.jpg" alt="" /></li>
 <li><img src="image/pic3.jpg" alt="" /></li>
 </ul>
 <ol>
 <li class="on"></li>
 <li></li>
 <li></li>
 <li></li>
 </ol>
 <a href="javascript:;" rel="external nofollow" rel="external nofollow" class="prev" id="prev"><</a>
 <a href="javascript:;" rel="external nofollow" rel="external nofollow" class="next" id="next">></a> 
</div>

css代码:

*{margin: 0; padding: 0;}
li{ list-style: none;}
#tab{
 width: 670px;
 height: 240px;
 border: 1px solid #ccc;
 margin: 50px auto;
 position: relative;
}
#tab ul{
 width: 2680px;
 height: 240px;
 position: absolute;
 left: 0;
 top: 0;
 overflow: hidden;
}
#tab ul li{
 float: left;
 width: 670px;
}
#tab ul li img{
 width: 670px;
}
#tab ol{
 width: 80px;
 position: absolute;
 bottom: 10px;
 left: 50%;
 margin-left: -40px;
 overflow: hidden;
}
#tab ol li{
 float: left;
 width: 10px;
 height: 10px;
 background: #ccc;
 border-radius: 50%;
 margin: 5px;
 cursor: pointer;
}
#tab ol .on{
 background: #f00;
}
#tab .prev,#tab .next{
 display: none;
 width: 40px;
 height: 60px;
 background: rgba(0,0,0,.3);
 filter:alpha(opacity:30);
 text-decoration: none;
 text-align: center;
 line-height: 60px;
 font-size: 30px;
 color: #fff;
 position: absolute;
 top: 50%;
 margin-top: -30px;
}
#tab .prev{
 left: 0;
}
#tab .next{
 right: 0;
}

js 代码:

其中animate()是封装好的运动框架,最后面附有说明

window.onload = function(){
 var oTab = document.getElementById('tab');
 var oUl = oTab.getElementsByTagName('ul')[0];
 var aLi1 = oUl.children;
 var oOl = oTab.getElementsByTagName('ol')[0];
 var aLi2 = oOl.children;
 var prev = document.getElementById('prev');
 var next = document.getElementById('next');
 //设置ul的初始位置
 var iNow = 1; 
 oUl.style.left=-aLi1[0].offsetWidth*iNow+'px';
 //定时器
 var timer = null;

 //克隆第一张图片 添加在ul的最后面
 var oLi1 = aLi1[0].cloneNode(true);
 //克隆最后一张图片 添加在ul的最前面
 var oLi2 = aLi1[aLi1.length-1].cloneNode(true);
 oUl.appendChild(oLi1);
 oUl.insertBefore(oLi2,aLi1[0]);
 oUl.style.width = aLi1[0].offsetWidth*aLi1.length+"px";
 //鼠标移入tab: 关闭定时器,左右按钮显示
 oTab.onmouseover = function(){
 clearInterval(timer);
 prev.style.display = 'block';
 next.style.display = 'block';
 }
 //鼠标移出tab: 开启定时器,左右按钮隐藏
 oTab.onmouseout = function(){
 timer = setInterval(function(){
 toNext();
 },2000);
 prev.style.display = 'none';
 next.style.display = 'none';
 }
 //点击小圆点
 for(var i=0;i<aLi2.length;i++){
 (function(index){
 aLi2[index].onclick = function(){
 iNow = index+1;
 for(var i=0;i<aLi2.length;i++){
 aLi2[i].className = '';
 }
 aLi2[index].className = 'on';
 animate(oUl,{left: -iNow*aLi1[0].offsetWidth});
 }
 })(i);
 }
 //上一个
 prev.onclick=function(){
 iNow--;
 animate(oUl,{left: -iNow*aLi1[0].offsetWidth},{complete:function(){
 if(iNow == 0){
 iNow = aLi1.length-2;
 oUl.style.left=-aLi1[0].offsetWidth*iNow+'px';
 }
 for(var i=0;i<aLi2.length;i++){
 aLi2[i].className = '';
 }
 aLi2[iNow-1].className = 'on';
 }});
 }
 //下一个
 next.onclick=function(){
 toNext();
 }
 function toNext(){
 iNow++;
 animate(oUl,{left: -iNow*aLi1[0].offsetWidth},{complete:function(){
 if(iNow == aLi1.length-1){
 iNow = 1;
 oUl.style.left=-aLi1[0].offsetWidth*iNow+'px';
 }
 for(var i=0;i<aLi2.length;i++){
 aLi2[i].className = '';
 }
 aLi2[iNow-1].className = 'on';
 }});
 }
 //设置定时器
 timer = setInterval(function(){
 toNext();
 },2000);
}

封装的animate()运动框架

/*
 * 参数说明:
 * obj: 运动对象
 * json(json形式): 需要修改的属性
 * options(json形式): 
 * duration: 运动时间
 * easing: 运动方式(匀速、加速、减速)
 * complete: 运动完成后执行的函数
*/
function animate(obj,json,options){
 var options=options || {}; 
 var duration=options.duration || 500; //运动时间,默认值为500ms;
 var easing=options.easing || 'linear'; //运动方式,默认为linear匀速
 var start={};
 var dis={};

 for(var name in json){
 start[name]=parseFloat(getStyle(obj,name)); //起始位置
 dis[name]=json[name]-start[name]; //总距离
 }

 var count=Math.floor(duration/30); //总次数
 var n=0; //次数

 clearInterval(obj.timer);
 obj.timer=setInterval(function(){
 if(n>count){
 clearInterval(obj.timer);
 options.complete && options.complete();
 }else{
 for(var name in json){
 switch(easing){
 //匀速
 case 'linear':
 var a=n/count;
 var cur=start[name]+dis[name]*a; //当前位置
 break;
 //加速
 case 'ease-in':
 var a=n/count;
 var cur=start[name]+dis[name]*a*a*a;
 break;
 //减速
 case 'ease-out':
 var a=1-n/count;
 var cur=start[name]+dis[name]*(1-a*a*a);
 break;
 }
 if(name=='opacity'){
 obj.style.opacity=cur;
 obj.style.filter = 'alpha(opacity='+cur*100+')'; //兼容IE8及以下
 }else{
 obj.style[name]=cur+'px';
 }
 }
 }
 n++;
 },30);
}
//获取非行间样式
function getStyle(obj,sName){
 return (obj.currentStyle || getComputedStyle(obj,false))[sName];
}

以上这篇原生JS实现图片无缝滚动方法(附带封装的运动框架)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

下载本文
显示全文
专题