如何修改弹性幻灯片,使其无限循环

How to modify Elastislide so it loops infinitely

本文关键字:幻灯片 无限循环 何修改 修改      更新时间:2023-09-26

我一直在寻找一个图像轮播,它可以一次显示多张图像,响应迅速并无限循环。

弹性滑块似乎是最合适的(http://tympanus.net/Development/Elastislide/index2.html)。

我能找到的唯一其他实用选择是约翰·尼古拉基斯的液体旋转木马,它似乎有点旧,不那么优雅。

我有Elastislide自动播放(有点),使用与 http://www.w3schools.com/js/js_timing.asp 显示的clearTimeout()方法类似的方法,但是一旦到达终点,它就会停止,因为时间只是调用下一个按钮(.es-nav-next)。

我希望有人可以帮助我修改 Elastislide 以使其无限循环 - 或者我愿意接受满足我的 3 个要求(上面列出的)的不同解决方案的建议。

目前,我正在开发OpenCart的本地安装,但是如果有帮助,我可以提供一个静态示例并提供一个链接。

任何帮助或建议将不胜感激,到目前为止,我已经花了很多时间在javascript:)

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

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

此代码应添加到 var 之后的 _initEvents 函数中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);

此代码创建一个无限循环,保留动画,并在元素多于页面上显示的元素时在两侧显示导航按钮。_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();
        } } ) );
    },

我通过破解 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();
    },

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

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

http://caroufredsel.dev7studios.com/

希望这能帮助其他人像我一样找到这篇文章。

- var 实例 = this; 之后的 _initEvents 函数中添加此代码; 以使弹性滑块自动播放。

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

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

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

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

// autoplay true || false
autoplay : true,
然后,您将能够在

设置选项时设置 autoplay 值(true 或 false),就像您在上面的示例代码中尝试的那样。

此代码应添加到 var 之后的 _initEvents 函数中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 之后的发展,此代码在未来的版本中可能不起作用。

这是针对旧版本的 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();
        } } ) );
    },