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 $this.find('.nfdscroll-prev').text(options.prevText); $this.find('.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: 2000, selected:'circle', prevText:'上一個', nextText:'下一個', deriction:'left', callback: function(index,$currentNode){ console.log(index) } }); </script> </body> </html>
實現的效果
  
里面ol、nfdscroll-prev等的樣式自己手動調整
