輪播的實現方式

来源:http://www.cnblogs.com/chuaWeb/archive/2016/07/27/nfdscroll.html
-Advertisement-
Play Games

1.閃現方式的輪播 不論述,實現比較簡單,效果也比較好 2.滑動輪播 以下麵的html代碼為例(向左滑動) 插件源碼:實現向左和向上輪播,手動切換也是向左和向上切換(手動切換關鍵源碼) 滑動輪播的實現方式主要有兩種 1)切換父元素margin-left,將第一個子元素不斷添加到父容器結尾 簡單實現 ...


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:
    <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>
    <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>

    js:
    $('.example').nfdscroll({
        startIndex:0,
        width:'266',
        height:'216',
        interval:2000,
        selected:'circle',
        prevText:'上一個',
        nextText:'下一個',
        deriction:'left',
        callback: function(index,$currentNode){
          console.log(index)
        }
    });

    * @example end
 * @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
    }
}
});
View Code

  一個完整的例子

<!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: 2000,
      selected:'circle',
      prevText:'上一個',
      nextText:'下一個',
      deriction:'left',
      callback: function(index,$currentNode){
          console.log(index)
      }
  });
  </script>
</body>
</html>

  實現的效果

  

  裡面ol、nfdscroll-prev等的樣式自己手動調整

   

  如果覺得本文不錯,請點擊右下方【推薦】!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、jQuery的基本概念 1.1、什麼是jQuery js的方法庫,封裝了很多js的方法,需要的時候可以直接調用 1.2、使用jQuery的三個步驟 js:當頁面所有元素包括圖片,樣式文件,等所有資源都載入完才開始執行; jQuery:當頁面的文檔樹載入完成後就會執行,並不會等所有的文件都載入完成 ...
  • 一、前言 如果將前端比喻成一人,那麼Html就是這個人的骨骼脈絡,CSS則是這個人的身上的裝飾,JavaScript則是這個人的行為。作為一種腳本語言JavasSript具有著弱類型等特點。(在這裡我們要有一個明顯的認識JavasSript和Java是完全不同的兩種語言,他們之前一毛錢關係都沒有。之 ...
  • JavaScript第一天 1.前端三層 HTML 結構層 語義 骨架 css 表現層 審美 衣服 JavsScript 行為層 行為交互 動作 2.轉義字元\r\n\t \r return 回車符 \n new line 換行符 console.log可用 \t 製表符 \ 轉義字元 3.進位 0 ...
  • 如果元素有屬性 'position:absolute',containing block 由最近的 position 不是 static 的祖先建立,按下麵的步驟: 1、如果祖先是塊級元素,containing block 由祖先的 padding edge(除 margin, border 外的區 ...
  • 演示地址:http://admintemplate.webplus.org.cn/ v1.0 (2016/7/27) 扁平化風格 全屏支持 後臺管理不使用iframe,全ajax開發 許可權管理 商品管理 整合ckeditor及ckfinder 集成highcharts圖表插件 任何地方實現文件的上傳 ...
  • ECMAScript 變數:1.基本類型值(簡單數據段) 2.引用類型值(可能由過個值構成的對象) → 保存在記憶體中的對象 動態屬性: 只能給引用型值動態添加新屬性,以便將來使用。 複製變數值 : 基本類型值的複製 → 在變數對象上創建一個新值 → 複製給新變數(互不影響) 引用類型值的複製 → 將 ...
  • 序 聽過JS,聽過Node,也聽過Node.js,還聽過npm,然而並不是很清楚的知道都代表什麼,這兩天調介面,然後前端同學很忙,就自己把前端代碼拿過來跑了,也趁機瞭解一下這幾個概念,下邊做個小的總結吧。 Node和Node.js JS就不用說了,一種解釋型語言,前端用的較多,目前也出現在伺服器端。 ...
  • 首先,在製作網頁中,想實現在點擊提交按鈕後,根據當前按鈕的不同,將按鈕信息附加到鏈接的後邊,如下圖所示: 上圖中,鏈接後的id=LJQ,就是實現帶參數跳轉,之後便於在跳轉頁根據id=X;根據x不同,實現不同載入圖片等內容; 接下來是如何實現帶參數跳轉: 接下來講解,如何對帶參數鏈接進行解析呢? 解釋 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...