轮播的简单实现方法


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 相关文章推荐
基于jquery用于查询操作的实现代码
May 10 Javascript
JavaScript使用IEEE 标准进行二进制浮点运算产生莫名错误的解决方法
May 28 Javascript
JavaScript动态改变div属性的实现方法
Jul 22 Javascript
javascript 数组的定义和数组的长度
Jun 07 Javascript
浅谈JavaScript中的this指针和引用知识
Aug 05 Javascript
利用JS实现点击按钮后图片自动切换的简单方法
Oct 24 Javascript
Bootstrap modal 多弹窗之叠加关闭阴影遮罩问题的解决方法
Feb 27 Javascript
jQuery使用bind函数实现绑定多个事件的方法
Oct 11 jQuery
JavaScript分步实现一个出生日期的正则表达式
Mar 22 Javascript
详解@Vue/Cli 3 Invalid Host header 错误解决办法
Jan 02 Javascript
vue.js实现会动的简历(包含底部导航功能,编辑功能)
Apr 08 Javascript
解决Vue中的生命周期beforeDestory不触发的问题
Jul 21 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
解析二进制流接口应用实例 pack、unpack、ord 函数使用方法
2013/06/18 PHP
给PHP开发者的编程指南 第一部分降低复杂程度
2016/01/18 PHP
PHP制作登录异常ip检测功能的实例代码
2016/11/16 PHP
PHP getID3类的使用方法学习笔记【附getID3源码下载】
2019/10/18 PHP
javascript 图片上传预览-兼容标准
2009/06/01 Javascript
关于juqery radio写法的兼容性问题(新老版本jquery)
2010/06/14 Javascript
简单实用的全选反选按钮例子
2013/10/18 Javascript
jQuery动画效果animate和scrollTop结合使用实例
2014/04/02 Javascript
jQuery实现的输入框选择时间插件用法实例
2015/02/28 Javascript
深入分析Javascript跨域问题
2015/04/17 Javascript
理解Angular数据双向绑定
2016/01/10 Javascript
JavaScript性能优化总结之加载与执行
2016/08/11 Javascript
javascript实现二叉树的代码
2017/06/08 Javascript
Vue.js 中的 v-model 指令及绑定表单元素的方法
2018/12/03 Javascript
解决layer.confirm快速点击会重复触发事件的问题
2019/09/23 Javascript
Python入门篇之条件、循环
2014/10/17 Python
简单的Python2.7编程初学经验总结
2015/04/01 Python
windows环境下tensorflow安装过程详解
2018/03/30 Python
Python使用一行代码获取上个月是几月
2018/08/30 Python
浅谈Python类中的self到底是干啥的
2019/11/11 Python
使用Python实现批量ping操作方法
2020/05/06 Python
Python数据库封装实现代码示例解析
2020/09/05 Python
python定义具名元组实例操作
2021/02/28 Python
如何避免常见的6种HTML5错误用法
2017/11/06 HTML / CSS
全球知名旅游社区巴西站点:TripAdvisor巴西
2016/07/21 全球购物
迪拜航空官方网站:flydubai
2017/04/20 全球购物
英国网上电器商店:Electricshop
2020/03/15 全球购物
英国著名药妆店:Superdrug
2021/02/13 全球购物
英语专业学生个人求职信范文
2014/01/06 职场文书
公益活动策划方案
2014/01/09 职场文书
税务干部鉴定材料
2014/02/11 职场文书
施工安全生产承诺书
2014/05/23 职场文书
党性教育心得体会
2014/09/03 职场文书
导游词之沈阳清昭陵
2019/12/28 职场文书
Python 发送SMTP邮件的简单教程
2021/06/24 Python
MySQL实现用逗号进行拼接、以逗号进行分割
2022/12/24 MySQL