3

I've been searching for an image carousel that will display several images at once, is responsive and loops infinitely.

Elastislide seems to be the most suitable ( http://tympanus.net/Development/Elastislide/index2.html ).

The only other practical option I've been able to find is Liquid Carousel by John Nikolakis which seems to be a fair bit older and less elegant.

I've got Elastislide to autoplay (sort of), using a similar method to the The clearTimeout() Method shown at http://www.w3schools.com/js/js_timing.asp, but once it reaches the end it stops, as the timing is just calling the next button (.es-nav-next).

I'm hoping someone can help me with modifying Elastislide to make it loop infinitely - or I'm open to suggestions for a different solution which meets my 3 requirements (listed above).

At the moment I'm working on a local installation of OpenCart but I can put up a static sample and provide a link if that helps.

Any help or advice would be greatly appreciated, have spent many hours on this so far as I'm a complete amateur at javascript :)

4

7 回答 7

9

Elastislide 代码已经进化,上述解决方案不起作用。所以我开发了自己的解决方案。

此代码使 elastislide 自动播放,当到达最后一张幻灯片时,它返回到第一张幻灯片,比无限循环轮播更符合人体工程学。

这段代码应该加在_initEventsvar之后的函数中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);
于 2013-02-21T11:36:39.583 回答
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();
        } } ) );

    },
于 2012-11-03T17:15:41.397 回答
1

我遇到了与 OP 相同的麻烦,但无法使上述任何一种解决方案都能正常工作。不确定我是否做错了什么,或者自编写这些解决方案以来 Elastislide 代码是否发生了变化。

我找到了这个插件,它似乎满足了 OP 的所有相同标准:具有自动播放和无限循环的响应式轮播。

http://caroufredsel.dev7studios.com/

希望这可以帮助以与我相同的方式找到这篇文章的其他人。

于 2012-12-27T18:02:59.900 回答
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();

    },
于 2012-07-15T14:18:53.810 回答
1

在-var instance = this;之后的_initEvents函数中添加这段代码 使 elastislide 自动播放。

window.setInterval(function(){
                instance._slide('right');
            }, 7000);
于 2013-02-14T19:20:32.210 回答
0

这是针对旧版本的 elastislide,也许这段代码可以帮助某人。

这不是一个无限循环,但是当您到达缩略图轮播的末尾并单击下一步时,它会以动画方式返回到初始状态,如果您在开始并按下 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();
        } } ) );

    },
于 2014-12-19T00:57:36.340 回答
0

RoxySka 答案的略微修改版本,添加了使用初始化设置打开和关闭它的功能。

这将使 Elastislide 自动播放,当在最后一张幻灯片上时,它将返回到第一张幻灯片。

将此代码添加到$.Elastislide.defaults对象之后start : 0,

// autoplay true || false
autoplay : true,

然后,您将能够在设置autoplay选项时设置值(真或假),就像您在上面的示例代码中尝试做的那样。

这段代码应该加在_initEventsvar之后的函数中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 的发展,此代码可能无法在未来的版本中使用。

于 2013-06-06T22:55:46.740 回答