轮播的简单实现方法


Posted in Javascript onJuly 28, 2016

1.闪现方式的轮播

不论述,实现比较简单,效果也比较好

2.滑动轮播

以下面的html代码为例(向左滑动)

<div class="example" style="overflow: hidden; width: 266px;">   
 <ul style="width: 798px; float: left; height: 216px; margin-left: 0px;">
  <li style="width: 266px; float: left; height: 216px;"></li>
  <li style="width: 266px; float: left; height: 216px;"></li>
  <li style="width: 266px; float: left; height: 216px;"></li>
 </ul>
</div>

插件源码:实现向左和向上轮播,手动切换也是向左和向上切换(手动切换关键源码)

var all = $panel.find('>li'),
  prevAll = new Array();
prevAll[0] = all.eq(0);
//将目标节点前的所有节点都保存到prevAll中,动画结束后将这些节点一一按顺序加到容器的后面
for(var i = 1; i < len; i++){
  all.eq(i).css({display: 'none'});
  prevAll[i] = all.eq(i);
}
...

$panel.animate({ 'marginLeft': -options.width + 'px' }, options.duration, function() {
  for(var i = 0; i < prevAll.length; i++){
    $panel.append($(prevAll[i]).css({display: 'block'})); //将当前展示节点前的所有节点都加载到最后
  }
  $panel.css({ marginLeft: 0 });

})

滑动轮播的实现方式主要有两种

1)切换父元素margin-left,将第一个子元素不断添加到父容器结尾

简单实现

var $panel = $('example');
var scrollTimer = setInterval(function() {
      scrollNews($panel);
    }, 3000);
function $scrollNews(){
 $panel.animate({ 'marginLeft': '-266px' }, 500, function() {
  $panel.css({ marginLeft: 0 }).find('>li:first').appendTo($panel);
 })
}

这种方式有一个问题就是在老IE上可能存在兼容问题。

2) 累计方式设置父元素margin-left

不过在margin-left设置到最小的时候(滑动到最后一个元素),将第一个子元素的位置设置为最后一个子元素的后面,当最后一个元素滚动到第一个元素后,父元素margin-left置为0且第一个子元素的位置归位。举个简单代码例子

var $panel = $('.example'),
 index = 0;
var scrollTimer = setInterval(function() {
      scrollNews($panel);
    }, 3000);

function scrollNews(){
 if(++index >= 2){
  $panel.css({
   'paddingLeft': 266 + 'px'
  })
  $panel.find('>li:first').css({
   'position': 'absolute', 
   'left': 266*index + 'px'
  });
 }
 $panel.animate({ 'marginLeft': -266*index + 'px' }, 500, function() {
  if(++index > 3){
   $panel.css({ marginLeft: 0 });
  }
  if(index >= 3){
   index = 0;
   $panel.css({ 
    marginLeft: 0,
    'paddingLeft': 0 
   });
   $panel.find('>li:first').css({
    'position': 'static', 
     'left': 'auto'
    });
   }
 })
}

更复杂的滚动插件需要支持水平和垂直方向的滚动(四个方向)、可以手动切换焦点、可以翻上一个下一个。附上本人写完整的插件源码

插件源码jquery.nfdscroll.js:支持水平和垂直方向(四个方向)滚动,手动切换会随切换方向滚动

/**
 * @author '陈桦'
 * @date '2016-5-10'
 * @description 滑动轮播插件,支持水平和垂直方向滑动轮播
 *
 * @example 
  html:
  <div class="nfdnews_topnews example">
    <!-- 滚动内容ul -->
    <ul>
      <li><a href="xxx" target="_blank" title="xxx"></a></li>
      <li><a href="xxx" target="_blank" title="xxx"></a></li>
      <li><a href="xxx" target="_blank" title="xxx"></a></li>
      <li><a href="xxx" target="_blank" title="xxx"></a></li>
    </ul>   
    <!-- 焦点列表,可选 -->       
    <ol>
      <li class=""></li>
      <li class=""></li>
      <li class=""></li>
      <li class=""></li>
    </ol>
    <!-- 上一个和下一个,可选 -->
    <div>
      <a class="nfdscroll-prev" href="javascript:void(0);"></a>
      <a class="nfdscroll-next" href="javascript:void(0);"></a>
    </div>
  </div>

  js:
  $('.example').nfdscroll({
    startIndex:0,
    width:'266',
    height:'216',
    interval:2000,
    selected:'circle',
    prevText:'',
    nextText:'',
    deriction:'left',
    callback: function(index,$currentNode){
      console.log(index)
    }
  });
 * @param startIndex {Number} 默认从第几个滚动体开始滚动,可选(0-n,0表示第一个,默认为0)
 * @param width {Number} 滚动体宽度,可选(当宽度为0时表示不设置宽度)
 * @param height {Number} 滚动体高度,可选(当高度为0时表示不设置高度)
 * @param interval {Number} 间隔时间,单位毫秒, 当值为负时表示不进行自动滚动
 * @param duration {Number} 动画持续时间
 * @param selected {String} 滚动切换小图标(焦点列表)当前class
 * @param deriction {String} 滚动方向,支持left/right和top/bottom
 * @param callback {Function} 滑动动画结束时触发的回调,参数(index,$currentNode),index:轮播结束后展示的节点的索引;currentNode:轮播结束后当前展示的节点的jquery对象
 * @param prevText {String} 上一个按钮的文本,默认是"上一个"
 * @param nextText {String} 下一个按钮的文本,默认是"下一个"
 */
 jQuery.fn.extend({nfdscroll: function(options) {
  var defaultOpt = {
    startIndex: 0,
    width: 0,//滚动体宽度,可选(当宽度为0时表示不设置宽度)
    height: 0,//滚动体高度,可选(当高度为0时表示不设置高度度)
    interval: 1000,//间隔时间毫秒
    duration: 400,//动画持续时间
    selected:'selected',//滚动切换小图标当前class
    prevText:'上一个',
    nextText:'下一个',
    deriction:'left',//滚动方向
    callback: function(index,$currentNode){//每次滚动到新节点后马上触发,currentNode是当前展示的节点的jquery对象
    }
  },
  $this = this,
  $panel = $this.find('>ul'),//滚动容器
  $panelList = $panel.find('>li'),
  $selectList = $this.find('>ol>li'),//选择容器
  options = jQuery.extend(defaultOpt,options),
  animateFn,//滚动动画
  max = $panel.find(">li").length,//要滚动的节点的数量
  focusIndex = 0,//当前展示的节点的索引
  nfdscrollTimer = 0,//计时器
  inAnimation = false,//动画过程中不再响应其他动画
  isWaitting = false,//是否有未执行的等待动画
  waittingIndex;//未执行的等待动画的目标index

  $('.nfdscroll-prev').text(options.prevText);
  $('.nfdscroll-next').text(options.nextText);

  //只有一个展示,不需要轮播
  if($panelList.length <= 1){
    return;
  }
  //当前动画没有做完但是焦点已经切换到下一个地方,这个函数就是用来执行保障当前显示的页面和鼠标指定的目标一致的处理
  function doWaitting(){
    if(isWaitting){
      startScroll(waittingIndex);
    }
  }
  //开始轮播
  function startScroll(toIndex){
    stopScroll();
    if(inAnimation) {
      isWaitting = true;
      waittingIndex = toIndex;
      return;//动画过程中不再响应其他动画
    }else{
      isWaitting = false;
    }

    if(toIndex == undefined){
      if(options.interval > 0){        
        nfdscrollTimer = setInterval(function(){
          animateFn(toIndex);
        },options.interval);
      }        
    //跳到指定index后再计时
    }else{
      animateFn(toIndex);
      if(options.interval > 0){
        nfdscrollTimer = setInterval(function(){
          animateFn();
        },options.interval);
      }
    }
  }
  //停止轮播
  function stopScroll(){
    clearInterval(nfdscrollTimer);
  }
  //向左向右滚动动画
  //参数toIndex: number,滚动到指定index
  function leftRightAnimate(toIndex){
    //默认滚动方式
    if(toIndex == undefined){
      if(options.deriction == 'left'){
        toIndex = focusIndex + 1;
      }else{
        toIndex = focusIndex - 1;
      }      
      
    }
    if(toIndex != focusIndex){
      inAnimation = true;

      //当前为最后一个轮播体时的处理
      var tInd = 0;
      if(toIndex >= max){//最后一张图片继续滚动时
        $panel.css({
          'paddingLeft': options.width + 'px'
        })
        $panelList.eq(0).css({
          'position': 'absolute', 
          'left': options.width*toIndex + 'px'
        });
        tInd = 0;
      }else if(toIndex < 0){//仅仅在当前图片是第一个图片,然后点击上一个图片的时候出现
        //当前为最后一个轮播体时的处理
        $panelList.eq(max - 1).css({
          'position': 'absolute', 
          'left': -options.width + 'px'
        });
        tInd = max - 1;
      }else{
        tInd = toIndex;
      }
      
      //先将焦点切换过去
      $selectList.filter('.' + options.selected).removeClass(options.selected)
        .end().eq(tInd).addClass(options.selected); 

      $panel.animate({ 'marginLeft': -options.width*toIndex + 'px' }, options.duration, function() {
        focusIndex = tInd;

        if(toIndex >= max){//最后一张图片继续滚动时
          $panel.css({ 
            'marginLeft': 0,
            'paddingLeft': 0 
          });
          $panelList.eq(0).css({
            'position': 'static', 
            'left': 'auto'
          });
        }else if(toIndex < 0){//仅仅在当前图片是第一个图片,然后点击上一个图片的时候出现
          $panel.css({ 
            'marginLeft': -options.width*focusIndex + 'px',
            'paddingLeft': 0 
          });
          $panelList.eq(max - 1).css({
            'position': 'static', 
            'left': 'auto'
          });
        }
        
        options.callback(focusIndex,$panelList.eq(focusIndex));
        inAnimation = false;

        doWaitting();
      })
    }
  }

  //向上向下滚动动画
  function topBottomAnimate(toIndex){
    //默认滚动方式
    if(toIndex == undefined){
      if(options.deriction == 'top'){
        toIndex = focusIndex + 1;
      }else{
        toIndex = focusIndex - 1;
      }       
    }
    if(toIndex != focusIndex){
      inAnimation = true;

      //当前为最后一个轮播体时的处理
      var tInd = 0;
      if(toIndex >= max){
        $panel.css({
          'paddingTop': options.height + 'px'
        })
        $panelList.eq(0).css({
          'position': 'absolute', 
          'top': options.height*toIndex + 'px'
        });
        tInd = 0;
      }else if(toIndex < 0){//仅仅在当前图片是第一个图片,然后点击上一个图片的时候出现
        //当前为最后一个轮播体时的处理
        $panelList.eq(max - 1).css({
          'position': 'absolute', 
          'top': -options.height + 'px'
        });
        tInd = max - 1;
      }else{
        tInd = toIndex;
      }

      //先将焦点切换过去
      $selectList.filter('.' + options.selected).removeClass(options.selected)
        .end().eq(tInd).addClass(options.selected);

      $panel.animate({ 'marginTop': -options.height*toIndex + 'px' }, options.duration, function() {
        focusIndex = tInd;

        if(toIndex >= max){
          $panel.css({ 
            marginTop: 0,
            'paddingTop': 0 
          });
          $panelList.eq(0).css({
            'position': 'static', 
            'top': 'auto'
          });
        }else if(toIndex < 0){//仅仅在当前图片是第一个图片,然后点击上一个图片的时候出现
          $panel.css({ 
            'marginTop': -options.height*focusIndex + 'px',
            'paddingTop': 0 
          });
          $panelList.eq(max - 1).css({
            'position': 'static', 
            'top': 'auto'
          });
        }

        options.callback(focusIndex,$panelList.eq(focusIndex));
        inAnimation = false;

        doWaitting();
      })
    }
  }
  function bindEvent(){
    //绑定事件
    $this.on('mouseover',function(){
      stopScroll();
           
    }).on('mouseout',function(){
      startScroll();
    }).on('click', '.nfdscroll-prev', function(){
      stopScroll();
      startScroll(focusIndex - 1);
    }).on('click', '.nfdscroll-next', function(){
      stopScroll();
      startScroll(focusIndex + 1);
    })
    $selectList.on('mouseover',function(){
      stopScroll();
      if(!$(this).is('.' + options.selected)){
        startScroll($(this).index());
      } 
    });
  }
  function init(){
    $this.css({
      position: 'relative',
      overflow: 'hidden'
    });
    $panel.css({
      position: 'relative'
    })
    focusIndex = options.startIndex;//默认从startIndex开始滚动
    $selectList.eq(focusIndex).addClass(options.selected);//先将焦点切换过去
    if(options.deriction == 'left' || options.deriction == 'right'){
      //初始化样式,实际上不应该插件里面来做样式,应该使用者自己就保证样式没有问题
      var cssO = {
        width: options.width,
        'float': 'left'
      }
      $this.css({
        width: options.width
      });//只需要管宽度即可
      if(options.height){
        cssO.height = options.height;
      }
      var leng = $panel.find('>li').css(cssO).length;
      $panel.css({
        width: options.width * leng + 'px',
        'marginLeft': -options.width*focusIndex + 'px'
      });
      
      animateFn = leftRightAnimate;
    }else if(options.deriction == 'top' || options.deriction == 'bottom'){
      var cssO = {
        height: options.height
      }
      $this.css({
        height: options.height
      });//只需要管高度度即可
      if(options.width){
        cssO.width = options.width;
      }
      var leng = $panel.find('>li').css(cssO).length;
      $panel.css({
        height: options.height * leng + 'px',
        'marginTop': -options.height*focusIndex + 'px'
      });

      animateFn = topBottomAnimate;
    }else{
      alert('插件只支持left/right/top/bottom四种方向上的滚动');
      return;
    }
    
    startScroll();
  }
  
  bindEvent();
  init();

  return {
    'stopScroll': stopScroll,
    'startScroll': startScroll
  }
}
});

一个完整的例子

<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
 <title>轮播测试例子</title>
 <style type="text/css">
  body,ul,ol{margin: 0; padding: 0;}
  ul,ol{list-style: none;}
  .li1{background-color: #000;}
  .li2{background-color: #333;}
  .li3{background-color: #666;}
  .li4{background-color: #999;}
  .example{margin-left: 300px;}
  .example ol {
   position: absolute;
   padding-left: 80px;
   width: 186px;
   height: 20px;
   top: 186px;
   left: 0px;
   background: #fff;
   cursor: pointer;
  }
  ol li{
   float: left;
   width: 10px;
   height: 10px;
   margin: 5px;
   background: #ff0;
   border-radius: 10px;
  }
  ol li.circle{
   background: #f00;
  }
 </style>
</head>

<body>
 <div class="example">
  <!-- 滚动内容ul -->
  <ul>
    <li class="li1"><a href="xxx" target="_blank" title="xxx"></a></li>
    <li class="li2"><a href="xxx" target="_blank" title="xxx"></a></li>
    <li class="li3"><a href="xxx" target="_blank" title="xxx"></a></li>
    <li class="li4"><a href="xxx" target="_blank" title="xxx"></a></li>
  </ul>   
  <!-- 焦点列表,可选 -->       
  <ol>
    <li class=""></li>
    <li class=""></li>
    <li class=""></li>
    <li class=""></li>
  </ol>
  <!-- 上一个和下一个,可选 -->
  <div>
    <a class="nfdscroll-prev" href="javascript:void(0);"></a>
    <a class="nfdscroll-next" href="javascript:void(0);"></a>
  </div>
</div>
 <script type="text/javascript" src="common/jquery.js"></script>
 <script type="text/javascript" src="common/jquery.nfdscroll.js"></script>
 <script type="text/javascript">
 $('.example').nfdscroll({
   startIndex:0,
   width:'266',
   height:'216',
   interval:-1,//2000,
   selected:'circle',
   prevText:'上一个',
   nextText:'下一个',
   deriction:'left',
   callback: function(index,$currentNode){
     console.log(index)
   }
 });
 </script>
</body>
</html>

实现的效果

轮播的简单实现方法

里面ol、nfdscroll-prev等的样式自己手动调整

以上这篇轮播的简单实现方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
跨浏览器的事件对象介绍
Jun 27 Javascript
jQuery写的日历(包括日历的样式及功能)
Apr 23 Javascript
js实现拉伸拖动iframe的具体代码
Aug 03 Javascript
javascript将url中的参数加密解密代码
Nov 17 Javascript
jQuery实现带滚动线条导航效果的方法
Jan 30 Javascript
Javascript中的apply()方法浅析
Mar 15 Javascript
jQuery validate插件实现ajax验证重复的2种方法
Jan 22 Javascript
怎么引入(调用)一个JS文件
May 26 Javascript
微信小程序实现滑动删除效果
May 19 Javascript
基于node下的http小爬虫的示例代码
Jan 11 Javascript
Vue3.x源码调试的实现方法
Oct 13 Javascript
JS中类的静态方法,静态变量,实例方法,实例变量区别与用法实例分析
Mar 14 Javascript
关于JS变量和作用域详解
Jul 28 #Javascript
jquery轮播的实现方式 附完整实例
Jul 28 #Javascript
AngularJS入门教程中SQL实例详解
Jul 27 #Javascript
AngularJS入门教程之表格实例详解
Jul 27 #Javascript
基于jQuery实现仿微博发布框字数提示
Jul 27 #Javascript
AngularJS入门教程之Select(选择框)详解
Jul 27 #Javascript
关于JS中的方法是否加括号的问题
Jul 27 #Javascript
You might like
php中使用$_REQUEST需要注意的一个问题
2013/05/02 PHP
PHP实现将科学计数法转换为原始数字字符串的方法
2014/12/16 PHP
解决laravel上传图片之后,目录有图片,但是访问不到(404)的问题
2019/10/14 PHP
再谈ie和firefox下的document.all属性
2009/10/21 Javascript
基于Jquery的动态添加控件并取值的实现代码
2010/09/24 Javascript
jQuery 源码分析笔记(6) jQuery.data
2011/06/08 Javascript
js 定时器setTimeout无法调用局部变量的解决办法
2013/11/28 Javascript
Javascript遍历table中的元素示例代码
2014/07/08 Javascript
深入理解JavaScript系列(37):设计模式之享元模式详解
2015/03/04 Javascript
JavaScript实现模仿桌面窗口的方法
2015/07/18 Javascript
基于jQuery仿淘宝产品图片放大镜代码分享
2020/06/23 Javascript
jQuery+json实现的简易Ajax调用实例
2015/12/14 Javascript
BackBone及其实例探究_动力节点Java学院整理
2017/07/14 Javascript
浅谈JavaScript的innerWidth与innerHeight
2017/10/12 Javascript
vue+socket.io+express+mongodb 实现简易多房间在线群聊示例
2017/10/21 Javascript
浅谈vue首屏加载优化
2018/06/28 Javascript
Vue-router 中hash模式和history模式的区别
2018/07/24 Javascript
vue 实现用户登录方式的切换功能
2020/04/14 Javascript
elementui更改el-dialog关闭按钮的图标d的示例代码
2020/08/04 Javascript
前端vue如何使用高德地图
2020/11/05 Javascript
Python爬虫信息输入及页面的切换方法
2018/05/11 Python
浅谈pyqt5中信号与槽的认识
2019/02/17 Python
python实现字符串加密成纯数字
2019/03/19 Python
PyCharm无法引用自身项目解决方式
2020/02/12 Python
使用jupyter Nodebook查看函数或方法的参数以及使用情况
2020/04/14 Python
Python使用tkinter实现小时钟效果
2021/02/22 Python
Html5让容器充满屏幕高度或自适应剩余高度的布局实现
2020/05/14 HTML / CSS
英国第一的滑雪服装和装备零售商:Snow+Rock
2020/02/01 全球购物
外贸学院会计专业应届生求职信
2013/11/14 职场文书
土木工程个人自荐信范文
2013/11/30 职场文书
中班幼儿评语大全
2014/04/30 职场文书
社区活动总结报告
2014/05/05 职场文书
关于运动会广播稿50字
2014/10/18 职场文书
员工开除通知书
2015/04/25 职场文书
美丽心灵观后感
2015/06/01 职场文书
vue实现同时设置多个倒计时
2021/05/20 Vue.js