2012-06-02 47 views
3

我一直在尋找一個圖像旋轉木馬,一次顯示幾個圖像,是響應和循環無限。如何修改Elastislide,使其無限循環

Elastislide似乎是最合適的(http://tympanus.net/Development/Elastislide/index2.html)。

我唯一能找到的其他實用選擇是John Nikolakis的液體旋轉木馬,看起來有點老舊,不那麼優雅。

我有Elastislide自動播放(使用類似的方法來清除TimeTimeout()方法顯示在http://www.w3schools.com/js/js_timing.asp,但一旦它達到結束它停止,因爲時間只是調用下一個按鈕( .ES-NAV-NEXT)。

我希望有人可以幫助我修改Elastislide以使其循環無限 - 或者我願意接受針對滿足我的3個要求(上面列出的)的不同解決方案的建議。

目前我正在開發一個OpenCart的本地安裝,但我可以搭起一個靜態示例並提供一個鏈接(如果有幫助的話)。

任何幫助或建議將不勝感激,迄今已在這個花了很多時間爲我在JavaScript的:)

回答

1

我做到了由黑客toggleControls()函數完全業餘,而不是隱藏附加第一個項目的導航/添加最後一個項目。當你在項目的開始/結束時自動更正金額實際上有助於做到這一點。不幸的是,如果使用緩解措施,它會打破動畫。

// modified version of _toggleControls 
    _toggleControls  : function(dir, status) { 

     // show/hide navigation buttons 
     if(dir && status) { 
      if(status === 1) 
       (dir === 'right') ? this.$navNext.show() : this.$navPrev.show(); 
      else 
       if (dir === 'right') { 

        this.$slider.append(this.$slider.children('li:first').clone()) ; 
        this.$slider.children('li:first').remove(); 
       } else { 

        this.$slider.prepend(this.$slider.children('li:last').clone()) ; 
        this.$slider.children('li:last').remove(); 
       } 
     } 
     else if(this.current >= this.itemsCount - 1 || this.fitCount >= this.itemsCount) 
       this.$navNext.hide(); 

    }, 
+0

很不錯的答案,你有我的投票,但還有一件事,如何防止轉盤滑回第一項幾秒鐘,點擊導航控件後? – motto

2

此代碼創建無限循環,保留動畫並在兩側顯示導航按鈕(如果頁面上顯示的元素多於此元素)。 _toggleControls功能與原始版本保持一致。

// modified version of _slide 
_slide    : function(dir, val, anim, callback) { 

     // if animating return 
     if(this.$slider.is(':animated')) 
      return false; 

     // current margin left 
     var ml  = parseFloat(this.$slider.css('margin-left')); 

     // val is just passed when we want an exact value for the margin left (used in the _slideToCurrent function) 
     if(val === undefined) { 

      // how much to slide? 
      var amount = this.fitCount * this.itemW, val; 

      if(amount < 0) return false; 

      // make sure not to leave a space between the last item/first item and the end/beggining of the slider available width 
      if(dir === 'right' && this.sliderW - (Math.abs(ml) + amount) < this.visibleWidth) { 
       for (var i=0;i<this.fitCount;i++) { // add elements 
        this.$slider.css('margin-left', '+=' + this.itemW); 
        this.$slider.append(this.$slider.children('li:first').clone()) ; 
        this.$slider.children('li:first').remove(); 
       } 
      } else if (dir === 'left' && Math.abs(ml) - amount < 0) { 
       for (var i=0;i<this.fitCount;i++) { // add elements 
        this.$slider.css('margin-left', '-=' + this.itemW); 
        this.$slider.prepend(this.$slider.children('li:last').clone()) ; 
        this.$slider.children('li:last').remove(); 
       } 
      } 

      (dir === 'right') ? val = '-=' + amount : val = '+=' + amount 

     } 
     else { 
      var fml  = Math.abs(val); // future margin left 

      if(Math.max(this.sliderW, this.visibleWidth) - fml < this.visibleWidth) { 
       val = - (Math.max(this.sliderW, this.visibleWidth) - this.visibleWidth); 
       if(val !== 0) 
        val += this.options.margin; // decrease the margin left if not on the first position 

       // show/hide navigation buttons 
       this._toggleControls('right', -1); 
       fml = Math.abs(val); 
      } 

      // show/hide navigation buttons 
      if(this.fitCount < this.itemsCount) 
       this._toggleControls('left', 1); 
      else 
       this._toggleControls('left', -1); 

      if(Math.max(this.sliderW, this.visibleWidth) - this.visibleWidth > fml + this.options.margin) 
       this._toggleControls('right', 1); 
      else 
       this._toggleControls('right', -1); 

     } 

     $.fn.applyStyle = (anim === undefined) ? $.fn.animate : $.fn.css; 

     var sliderCSS = { marginLeft : val }; 

     var instance = this; 

     this.$slider.applyStyle(sliderCSS, $.extend(true, [], { duration : this.options.speed, easing : this.options.easing, complete : function() { 
      if(callback) callback.call(); 
     } })); 

    }, 
1

我和OP有同樣的問題,但無法使上述兩種解決方案都能正常工作。不確定自己是否做錯了什麼,或者自從這些解決方案寫完以後Elastislide代碼已經發生了變化。

我發現這個插件,這似乎滿足所有相同的標準,OP有:自動播放和無限循環響應旋轉木馬。

http://caroufredsel.dev7studios.com/

希望這可以幫助其他人認爲找到這篇文章以同樣的方式我做到了。

+0

不錯! Thx alot :) – william

1

將此代碼添加到_initEvents函數後 - var instance = this;使彈力膜自動播放。

window.setInterval(function(){ 
       instance._slide('right'); 
      }, 7000); 
+0

這會讓它自動播放,但不會考慮當滑動條到達最後一張幻燈片或用戶手動點擊下一個按鈕時會發生什麼。 這將停在最後一張幻燈片上。 如果用戶在6500 ms標記處手動下一次,滑塊將連續兩次向前移動。 – ORyan

9

Elastislide代碼已經發展並且上述解決方案不起作用。所以我開發了我自己的解決方案。

此代碼使彈力膜自動播放,當到達最後一張幻燈片時,它返回到第一張幻燈片比無限循環caroussel更符合人體工程學。

此代碼應在_initEvents功能被添加VAR後self = this;

var translation = 0; 
// width/height of an item (<li>) 
var itemSpace = this.options.orientation === 'horizontal' ? this.$items.outerWidth(true) : this.$items.outerHeight(true); 
// total width/height of the <ul> 
var totalSpace = this.itemsCount * itemSpace; 
// visible width/height 
var visibleSpace = this.options.orientation === 'horizontal' ? this.$carousel.width() : this.$carousel.height(); 
//slide auto 
window.setInterval(function(){ 
    //test if we should go to next slide or return to first slide 
    if(totalSpace > translation + visibleSpace) 
    { 
     //go to next slide 
     self._slide('next'); 
     //update translation 
     translation += visibleSpace; 
    } 
    else 
    { 
     //return to first slide (infinite loop is too bad for ergonomics) 
     self._slideTo(0); 
     //set translation to 0 
     translation = 0; 
    } 
}, 7000); 
+0

確認!這有效,謝謝你的真棒更新+1投注 插入代碼到「_initEvents:function()」中的文件「jquery.elastislide.js」,就在「self = this」之後。 – rockit

0

RoxySka的答案稍作修改的版本,加入到與初始化設置打開和關閉的能力。

這將使Elastislide自動播放,並且在最後一張幻燈片上它將返回到第一張幻燈片。

添加以下代碼到$.Elastislide.defaults對象start : 0,後:

// autoplay true || false 
autoplay : true, 

然後您就必須設置autoplay值(true或false)當您設置的選項了,因爲你的能力試圖在上面的示例代碼中做。

此代碼應在_initEvents功能被添加VAR後self = this;

 if(this.options.autoplay == true){ 
      var translation = 0; 
      // width/height of an item (<li>) 
      var itemSpace = this.options.orientation === 'horizontal' ? this.$items.outerWidth(true) : this.$items.outerHeight(true); 
      // total width/height of the <ul> 
      var totalSpace = this.itemsCount * itemSpace; 
      // visible width/height 
      var visibleSpace = this.options.orientation === 'horizontal' ? this.$carousel.width() : this.$carousel.height(); 
      //slide auto 
      window.setInterval(function(){ 
       //test if we should go to next slide or return to first slide 
       if(totalSpace > translation + visibleSpace) 
       { 
        //go to next slide 
        self._slide('next'); 
        //update translation 
        translation += visibleSpace; 
       } 
       else 
       { 
        //return to first slide 
        self._slideTo(0); 
        //set translation to 0 
        translation = 0; 
       } 
      }, 7000); 
     } 

要知道,作爲Elastislide演變過去V1.1.0該代碼可能不會在將來版本。

0

這是一個老版本的elastislide,也許這個代碼可以幫助某人。

這不是一個無限循環,但是當您到達縮略圖旋轉木馬的末尾並單擊next時,它會返回動畫到初始狀態,並且如果您在開始時按下prev按鈕,將移動到最後的縮略圖圖像。

首先你必須評論(或刪除)_toggleControls的所有行,這樣我們就避免了導航中的按鈕被隱藏。

,然後改變_slide的代碼:

 _slide    : function(dir, val, anim, callback) { 

     var ml  = parseFloat(this.$slider.css('margin-left')); 

     // val is just passed when we want an exact value for the margin left (used in the _slideToCurrent function) 
     if(val === undefined) { 

      // how much to slide? 
      var amount = this.fitCount * this.itemW, val; 

      if(amount < 0) return false; 
      // make sure not to leave a space between the last item/first item and the end/beggining of the slider available width 
      if(dir === 'right' && this.sliderW - (Math.abs(ml) + amount) < this.visibleWidth) {     
       amount = this.sliderW - (Math.abs(ml) + this.visibleWidth) - this.options.margin; // decrease the margin left 
       //Loop to the beginning 
       if (amount === 0) { 
        this.current = 0;      
        amount = this.sliderW - this.visibleWidth; 
        anim = undefined; 
        dir = 'left'; 
       } 
      } 
      else if(dir === 'left' && Math.abs(ml) - amount < 0) { 
       amount = Math.abs(ml); 
       //Loop to the end 
       if ($(".es-carousel ul").css("margin-left") === "0px") { 
        this.current = this.itemsCount - 1; 
        amount = -(this.sliderW - this.visibleWidth);      
        anim = undefined; 
       } 
      } 
      else { 
       var fml; // future margin left 
       (dir === 'right') 
        ? fml = Math.abs(ml) + this.options.margin + Math.abs(amount) 
        : fml = Math.abs(ml) - this.options.margin - Math.abs(amount);      
      } 

      (dir === 'right') ? val = '-=' + amount : val = '+=' + amount;     
     } 
     else { 
      var fml  = Math.abs(val); // future margin left 

      if(Math.max(this.sliderW, this.visibleWidth) - fml < this.visibleWidth) { 
       val = - (Math.max(this.sliderW, this.visibleWidth) - this.visibleWidth); 
       if(val !== 0)      
        val += this.options.margin; // decrease the margin left if not on the first position       
       fml = Math.abs(val); 
      } 
     } 

     $.fn.applyStyle = (anim === undefined) ? $.fn.animate : $.fn.css; 

     var sliderCSS = { marginLeft : val }; 

     var instance = this; 

     this.$slider.stop().applyStyle(sliderCSS, $.extend(true, [], { duration : this.options.speed, easing : this.options.easing, complete : function() { 
      if(callback) callback.call(); 
     } })); 

    },