2013-04-08 74 views
22

我不知道是什麼是最好的(好可讀的代碼,病蟲害實踐代碼的可重用性)的概念來打造一個無限 - 圖片 - 環 - 滑塊使用JavaScript/jQuery的一個網站?我不知道如何編碼幻燈片,但是什麼藍圖符合上述要求。 我的問題的主要焦點是如何安排圖片以獲得無限循環滑塊的印象。無限循環滑塊概念

通過看代碼從不同的滑塊我遇到了兩個解決方案:

- 更改所有圖像的z-index的每個顯示下一/上一個影像的時間。

- 更改圖像在DOM中的位置。

但審視和理解他人的代碼是非常耗時的 - 這就是爲什麼我問這個問題:-)

回答

49

TL;博士 - 例如:http://jsbin.com/ufoceq/8/


一個簡單的方法來創建一個無限的圖像滑塊沒有太多的努力,如下所示:讓我們說,爲了簡單起見,您有<n>圖像在循環中滑動,以便在nth想象的下一張照片是1st(反之亦然)。

的想法是讓

  • 最後一個圖像的克隆的第一個之前被預先計劃建立第一個和最後圖像的克隆;
  • 第一張圖片的克隆被追加到最後一張圖片的後面。

無論您的圖片的數量是多少,您至少需要追加2個克隆元素。

再一次爲了簡單起見,假設所有圖像都是100px寬,並且它們被包裝在一個容器中,您可以左右移動到與overflow: hidden相關的修剪遮罩中。然後,所有圖像可以很容易地與容器上的display: inline-blockwhite-space: nowrap對齊(現在更容易使用flexbox)。

對於n = 4 DOM結構是這樣的:

offset(px)  0  100  200  300  400  500 
images   | 4c | 1 | 2 | 3 | 4 | 1c 

/*     ^^          ^^ 
     [ Clone of the last image ]    [ Clone of the 1st image ] 
*/ 

在開始的時候,您的容器將被定位left: -100px(或者也margin-left: -100pxor even better (for a matter of performance)transform: translateX(-100px)),因此滑塊可以顯示第一張圖像。要從一個圖像切換到另一個,您需要在您之前選擇的同一個屬性上應用JavaScript動畫。

當你的滑蓋是目前在4 形象,你必須從圖像4切換到1c,這樣的想法是在動畫結束不久,在真正的重新定位你的滑蓋包裝執行的回調1 st圖像偏移(例如您設置left: -100px到容器)

這類似於當你滑板目前位於1 ST元素:顯示你只需要從圖像1執行動畫4c以前的形象,當動畫已完成您只需移動容器,以便滑塊位於圖像偏移量(例如,將left: -400px設置爲容器)。


你可以看到上面的小提琴效果:這是最小js/jquery代碼我使用(當然代碼甚至可以優化,使項目的寬度沒有硬編碼到腳本)

$(function() { 

    var gallery = $('#gallery ul'), 
     items = gallery.find('li'), 
     len  = items.length, 
     current = 1, /* the item we're currently looking */ 

     first = items.filter(':first'), 
     last = items.filter(':last'), 

     triggers = $('button'); 

    /* 1. Cloning first and last item */ 
    first.before(last.clone(true)); 
    last.after(first.clone(true)); 

    /* 2. Set button handlers */ 
    triggers.on('click', function() { 

    var cycle, delta; 

    if (gallery.is(':not(:animated)')) { 

     cycle = false; 
     delta = (this.id === "prev")? -1 : 1; 
     /* in the example buttons have id "prev" or "next" */ 

     gallery.animate({ left: "+=" + (-100 * delta) }, function() { 

      current += delta; 

      /** 
      * we're cycling the slider when the the value of "current" 
      * variable (after increment/decrement) is 0 or when it exceeds 
      * the initial gallery length 
      */   
      cycle = !!(current === 0 || current > len); 

      if (cycle) { 
       /* we switched from image 1 to 4-cloned or 
        from image 4 to 1-cloned */ 
       current = (current === 0)? len : 1; 
       gallery.css({left: -100 * current }); 
      } 
     }); 
    } 

    }); 
}); 

正如前面提到的,這種解決方案並不需要真正的精力和談論的性能,而無需循環這種方法比較正常滑塊,它只需要做兩個額外的DOM插入時滑塊初始化一些(相當triv ial)額外的邏輯來管理後向/前向循環。

我不知道是否存在一個更簡單或更好的方法,但希望這有助於反正。

注意:如果您還需要有一個響應畫廊,也許this answer可以幫助過

+0

謝謝您的詳細解釋! – user1828928 2013-04-08 12:08:41

+0

@ user1828928如果您對現場示例感興趣,我創建了一個短小提琴 – fcalderan 2013-04-09 09:11:51

+0

對不起第一個標誌。我認爲電線已經穿過那裏,因爲你對這裏的wiki地位是正確的。 – 2013-04-10 01:19:48

1

非常感謝這篇文章的! 我有更新並使用上面的代碼。 我希望這會幫助大家。 差勁的開發人員。

<!DOCTYPE html> 
 
<html> 
 
<head lang="en"> 
 
    <meta charset="UTF-8"> 
 
    <title>Directive slider</title> 
 
    <style> 
 
     /* 四聯切換焦點圖 */ 
 
     .slides-wrapper{ position: relative; width: 100%; margin: 10px 0; } 
 
     .gallery { position: relative; width: 1200px; height: 180px; overflow:hidden; } 
 
     .gallery ul { font-size: 0; white-space: nowrap; position: absolute; top: 0; left: -1200px; margin: 0; padding: 0; } 
 
     .gallery li { display: inline-block; vertical-align: top; width: 1200px; height: 180px; white-space: normal; } 
 
     .gallery li img{ width: 298px; height:180px; padding: 1px; } 
 
     .gallery .arrow { background: url(/shop/templates/default/images/home_bg.png) no-repeat; background-size: 150px 223px; width: 35px; height: 70px; position: absolute; z-index: 2; top: 50px; cursor: pointer; opacity: 0;} 
 
     .gallery .prev { background-position: 1px -92px; left: 0;} 
 
     .gallery .next { background-position: -30px -92px; right: 0px;} 
 
    </style> 
 
    <style type="text/css"> 
 
     .demo_wrapper{ 
 
      margin: 0 auto; 
 
      width: 1200px; 
 
     } 
 
     .demo_wrapper .title{ 
 
      text-align: center; 
 
     } 
 
    </style> 
 
</head> 
 
<body> 
 
<div class="demo_wrapper"> 
 
    <div class="title"> 
 
     <h1>Directive slider (Published by fenmingyu)</h1> 
 
    </div> 
 
    <!-- demo content --> 
 
    <div class="slides-wrapper"> 
 
     <div class="gallery" id="top_sale_gallery"> 
 
      <ul> 
 
       <li> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-1.jpg?234" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-2.jpg?752" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-3.jpg?320" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-4.jpg?365" alt=""></a> 
 
       </li> 
 
       <li> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-1.jpg?852" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-2.jpg?746" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-3.jpg?525" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-4.jpg?550" alt=""></a> 
 
       </li> 
 
      </ul> 
 
      <div class='arrow prev'></div> 
 
      <div class='arrow next'></div> 
 
     </div> 
 
     <div class="gallery" id="top_goods_gallery"> 
 
      <ul> 
 
       <li> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-3-1.jpg?793" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-3-2.jpg?180" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-3-3.jpg?550" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-3-4.jpg?851" alt=""></a> 
 
       </li> 
 
       <li> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-1.jpg?234" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-2.jpg?752" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-3.jpg?320" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-1-4.jpg?365" alt=""></a> 
 
       </li> 
 
       <li> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-1.jpg?852" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-2.jpg?746" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-3.jpg?525" alt=""></a> 
 
        <a href="" target="_blank" title="" style="opacity: 1;"><img src="http://imgserv.5thmedia.cn/upload_test/shop/editor/web-102-104-2-4.jpg?550" alt=""></a> 
 
       </li> 
 
      </ul> 
 
      <div class='arrow prev'></div> 
 
      <div class='arrow next'></div> 
 
     </div> 
 
     <div style="clear: both;"></div> 
 
    </div> 
 
</div> 
 

 
</body> 
 
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script> 
 
<script type="text/javascript"> 
 
    $(function() { 
 
     $.fn.gallery = function(settings) { 
 
      var defaults = { 
 
       time: 3000, 
 
       direction:1 
 
      }; 
 
      var settings = $.extend(defaults, settings); 
 
      var gallery_wrapper = $(this), 
 
       gallery = gallery_wrapper.find('ul'), 
 
       items = gallery.find('li'), 
 
       len  = items.length, 
 
       current = 1, /* the current item we're looking */ 
 
       first = items.filter(':first'), 
 
       last = items.filter(':last'), 
 
       w = gallery.find('li').width(), 
 
       triggers = gallery_wrapper.find('.arrow'); 
 
      var show_slide = function(direction,w){ 
 
       gallery.animate({ left: "+=" + (-w * direction) }, function() { 
 

 
        current += direction; 
 

 
        /** 
 
        * we're cycling the slider when the the value of "current" 
 
        * variable (after increment/decrement) is 0 or when it exceeds 
 
        * the initial gallery length 
 
        */ 
 
        cycle = !!(current === 0 || current > len); 
 

 
        if (cycle) { 
 
         /* we switched from image 1 to 4-cloned or 
 
         from image 4 to 1-cloned */ 
 
         current = (current === 0)? len : 1; 
 
         gallery.css({left: -w * current }); 
 
        } 
 
       }); 
 
      }; 
 
      var picTimer = setInterval(function() { 
 
         show_slide(settings.direction,w); 
 
        }, 
 
        settings.time); 
 
      return this.each(function(){ 
 

 
       /* 1. Cloning first and last item */ 
 
       first.before(last.clone(true)); 
 
       last.after(first.clone(true)); 
 
       /* 2. Set button handlers */ 
 
       triggers.on('click', function() { 
 
        if (gallery.is(':not(:animated)')) { 
 

 
         var cycle = false; 
 
         settings.direction = ($(this).hasClass('prev'))? -1 : 1; 
 
         /* in the example buttons have id "prev" or "next" */ 
 
         show_slide(settings.direction,w); 
 
        } 
 
        clearInterval(picTimer); 
 
        picTimer = setInterval(function() { 
 
           show_slide(settings.direction,w); 
 
          }, 
 
          settings.time); 
 
       }); 
 
       /* hover show arrows*/ 
 
       show_slide(settings.direction,w); 
 

 
       gallery_wrapper.hover(function() { 
 
        $(this).find(".arrow").css("opacity", 0.0).stop(true, false).animate({ 
 
           "opacity": "0.3" 
 
          }, 
 
          300); 
 
       },function(){ 
 
        $(this).find(".arrow").css("opacity", 0.3).stop(true, false).animate({ 
 
           "opacity": "0" 
 
          }, 
 
          300); 
 
       }); 
 
      }); 
 
     }; 
 
     $('#top_goods_gallery.gallery').gallery(); 
 
     $('#top_sale_gallery.gallery').gallery({ 
 
      time: 5000, 
 
      direction:-1 
 
     }); 
 
    }); 
 
</script> 
 
</html>

TE和在我的項目中使用這個。

2

我剛剛創建的項目滑塊:檢查出來: https://github.com/lingtalfi/jItemSlider/blob/master/README.md

它的代碼600線,也許你可以簡單地瀏覽它。

它背後的想法是受netflix滑塊(截至2016年2月24日)的啓發。

基本上,它使用css轉換翻譯,因爲這些是瀏覽器中最快/最清晰的翻譯。

http://eng.wealthfront.com/2015/05/19/performant-css-animations/

現在滑運動背後的基本理念是,你只顯示當前可見切片, 但你也有左邊一個無形的切片,並在右側的另一個無形的切片。

而且,你也有兩個額外的項目,一邊一個,讓你的項目是這樣的:

以前的項目 - 上一個額外的項目 - 主要項目 - 下一個額外的項目 - 下一個項目

只有主要項目可見。 額外的項目部分可見。 上一個和下一個項目是不可見的。

更多細節在這裏: https://github.com/lingtalfi/jItemSlider/blob/master/doc/conception.md

現在,當你向右滑動(例如),你基本上更多的項目添加到右側, 然後刪除那些從左側。

這個技術是迄今爲止我遇到過的最大的技術,因爲你不需要處理一長串物品(使用 克隆而不移除隱形物品),這可以使動畫變慢。

注:我這個滑塊的第一次嘗試,實際上克隆不刪除,它的工作原理,但我不喜歡它: https://github.com/lingtalfi/jInfiniteSlider

此外,它是基於(而不是基於像素)項目,並在最終,這就是用戶期望的,因爲 一切都始終保持一致,因爲它應該是。