原生JS实现图片无缝滚动方法(附带封装的运动框架)


Posted in Javascript onOctober 01, 2017

话说轮播图效果是前端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实现图片无缝滚动方法(附带封装的运动框架)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js里的prototype使用示例
Nov 19 Javascript
javascript 冒泡排序 正序和倒序实现代码
Dec 14 Javascript
使用Plupload实现直接上传附件至七牛云存储
Dec 26 Javascript
jQuery的css() 方法使用指南
May 03 Javascript
jQuery实现响应鼠标事件的图片透明效果【附demo源码下载】
Jun 16 Javascript
jQuery多个版本和其他js库冲突的解决方法
Aug 11 Javascript
整理关于Bootstrap过渡动画的慕课笔记
Mar 29 Javascript
Vue.js实现文章评论和回复评论功能
May 30 Javascript
详解Angular4中路由Router类的跳转navigate
Jun 09 Javascript
微信小程序自定义模态对话框实例详解
Aug 16 Javascript
npm 下载指定版本的组件方法
May 17 Javascript
Angularjs实现页面模板清除的方法
Jul 20 Javascript
原生js封装运动框架的示例讲解
Oct 01 #Javascript
JS Testing Properties 判断属性是否在对象里的方法
Oct 01 #Javascript
基于原生js运动方式关键点的总结(推荐)
Oct 01 #Javascript
vuejs使用递归组件实现树形目录的方法
Sep 30 #Javascript
Easy UI动态树点击文字实现展开关闭功能
Sep 30 #Javascript
js实现轮播图的两种方式(构造函数、面向对象)
Sep 30 #Javascript
React实践之Tree组件的使用方法
Sep 30 #Javascript
You might like
php多功能图片处理类分享(php图片缩放类)
2014/03/14 PHP
php 根据URL下载远程图片、压缩包、pdf等文件到本地
2019/07/26 PHP
Javascript this指针
2009/07/30 Javascript
js实现鼠标移到链接文字弹出一个提示层的方法
2015/05/11 Javascript
针对初学者的jQuery入门指南
2015/08/15 Javascript
以Python代码实例展示kNN算法的实际运用
2015/10/26 Javascript
jQuery解析json数据实例分析
2015/11/24 Javascript
去除字符串左右两边的空格(实现代码)
2016/05/12 Javascript
JavaScript获取IP获取的是IPV6 如何校验
2016/06/12 Javascript
利用JQUERY实现多个AJAX请求等待的实例
2017/12/14 jQuery
浅谈vue单一组件下动态修改数据时的全部重渲染
2018/03/01 Javascript
代码分析vue中如何配置less
2018/09/28 Javascript
vue接通后端api以及部署到服务器操作
2020/08/13 Javascript
在VUE中使用lodash的debounce和throttle操作
2020/11/09 Javascript
python检测服务器是否正常
2014/02/16 Python
Python使用scrapy采集时伪装成HTTP/1.1的方法
2015/04/08 Python
Python中统计函数运行耗时的方法
2015/05/05 Python
Linux下为不同版本python安装第三方库
2016/08/31 Python
Python爬虫 scrapy框架爬取某招聘网存入mongodb解析
2019/07/31 Python
Django使用Jinja2模板引擎的示例代码
2019/08/09 Python
初次部署django+gunicorn+nginx的方法步骤
2019/09/11 Python
Keras 利用sklearn的ROC-AUC建立评价函数详解
2020/06/15 Python
Python包和模块的分发详细介绍
2020/06/19 Python
Python descriptor(描述符)的实现
2020/11/15 Python
一道SQL面试题
2012/12/31 面试题
.NET面试题:什么是反射
2016/09/30 面试题
生产车间主管岗位职责
2013/12/28 职场文书
校运会入场式解说词
2014/02/10 职场文书
大学生村官演讲稿
2014/04/25 职场文书
教师遵守党的政治纪律情况对照检查材料
2014/09/26 职场文书
酒店管理专业毕业生自我鉴定
2014/09/29 职场文书
2015年财政所工作总结
2015/04/25 职场文书
2015年秘书个人工作总结
2015/04/25 职场文书
党支部意见范文
2015/06/02 职场文书
繁星春水读书笔记
2015/06/30 职场文书
Django项目如何获得SSL证书与配置HTTPS
2021/04/30 Python