轮播的简单实现方法


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 相关文章推荐
javascript 对象比较实现代码
Apr 27 Javascript
10个基于浏览器的JavaScript调试工具分享
Feb 07 Javascript
js格式化货币数据实现代码
Sep 04 Javascript
分享JavaScript获取网页关闭与取消关闭的事件
Dec 13 Javascript
JavaScript实现级联菜单的方法
Jun 29 Javascript
深入理解逻辑表达式的用法 与或非的用法
Jun 06 Javascript
Bootstrap编写一个同时适用于PC、平板、手机的登陆页面
Jun 30 Javascript
js将字符串中的每一个单词的首字母变为大写其余均为小写
Jan 05 Javascript
js实现瀑布流效果(自动生成新的内容)
Mar 16 Javascript
深入理解Javascript中的作用域链和闭包
Apr 25 Javascript
微信小程序代码上传、审核发布小程序
May 18 Javascript
jstree中的checkbox默认选中和隐藏示例代码
Dec 29 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去掉从word直接粘贴过来的没有用格式的函数
2012/10/29 PHP
php生成4位数字验证码的实现代码
2015/11/23 PHP
PHP使用zlib扩展实现GZIP压缩输出的方法详解
2018/04/09 PHP
laravel框架中视图的基本使用方法分析
2019/11/23 PHP
JS 分号引起的一段调试问题
2009/06/18 Javascript
Javascript 刷新全集常用代码
2009/11/22 Javascript
javascript 获取页面的高度及滚动条的位置的代码
2010/05/06 Javascript
学习从实践开始之jQuery插件开发 对话框插件开发
2012/04/26 Javascript
20款非常优秀的 jQuery 工具提示插件 推荐
2012/07/15 Javascript
Nodejs express框架一个工程中同时使用ejs模版和jade模版
2015/12/28 NodeJs
js enter键激发事件实例代码
2016/08/17 Javascript
jQuery基本过滤选择器用法示例
2016/09/09 Javascript
vue购物车插件编写代码
2017/11/27 Javascript
JS实现简易换图时钟功能分析
2018/01/04 Javascript
Postman模拟发送带token的请求方法
2018/03/31 Javascript
Node.js HTTP服务器中的文件、图片上传的方法
2019/09/23 Javascript
node.js事件轮询机制原理知识点
2019/12/22 Javascript
解决python2.7用pip安装包时出现错误的问题
2017/01/23 Python
Python面向对象类编写细节分析【类,方法,继承,超类,接口等】
2019/01/05 Python
pyqt5与matplotlib的完美结合实例
2019/06/21 Python
用python实现英文字母和相应序数转换的方法
2019/09/18 Python
python数据处理——对pandas进行数据变频或插值实例
2020/04/22 Python
Django nginx配置实现过程详解
2020/09/10 Python
如何利用python读取micaps文件详解
2020/10/18 Python
举例讲解Python装饰器
2020/12/24 Python
python+opencv实现车道线检测
2021/02/19 Python
Html5+JS实现手机摇一摇功能
2015/04/24 HTML / CSS
全球知名鞋履品牌授权零售商:Journeys
2016/09/17 全球购物
优秀中专生推荐信
2013/11/17 职场文书
电子商务专员岗位职责
2013/12/11 职场文书
运动会邀请函范文
2014/01/31 职场文书
成品库仓管员岗位职责
2014/04/06 职场文书
党员一帮一活动总结
2014/07/08 职场文书
《跨越海峡的生命桥》教学反思
2016/02/18 职场文书
《七月的天山》教学反思
2016/02/19 职场文书
vue中的可拖拽宽度div的实现示例
2022/04/08 Vue.js