How to modify Elastislide so it loops infinitely

后端 未结 7 1129
庸人自扰
庸人自扰 2021-01-21 08:42

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

相关标签:
7条回答
  • 2021-01-21 09:06

    This code creates an infinite loop, preserves animations and shows navigation buttons on both sides if there are more elements than displayed on page. The _toggleControls function remains the same as in the original version.

    // 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();
            } } ) );
    
        },
    
    0 讨论(0)
  • 2021-01-21 09:17

    Slightly modified version of RoxySka's answer, adding the ability to turn it on and off with the initialization settings.

    This will make Elastislide autoplay and when on the last slide it will return to the first slide.

    Add this code to the $.Elastislide.defaults object after start : 0,:

    // autoplay true || false
    autoplay : true,
    

    You'll then have the ability to set the autoplay value (true or false) when you set the options up, as you were trying to do in your example code above.

    This code should be added in the _initEvents function after 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);
            }
    

    Be aware that as Elastislide evolves past v1.1.0 this code may not work in future versions.

    0 讨论(0)
  • 2021-01-21 09:20

    I was having the same trouble as the OP, but couldn't get either of the above solutions to work. Not sure if I was doing something wrong or if the Elastislide code had changed since those solutions were written.

    I found this plugin, which seems to satisfy all the same criteria that the OP had: responsive carousel with auto-play and infinite loop.

    http://caroufredsel.dev7studios.com/

    Hopefully this helps someone else that finds this article the same way I did.

    0 讨论(0)
  • 2021-01-21 09:24

    Add this code in the _initEvents function after - var instance = this; to make the elastislide autoplay.

    window.setInterval(function(){
                    instance._slide('right');
                }, 7000);
    
    0 讨论(0)
  • 2021-01-21 09:24

    This is for an old version of elastislide, Maybe this code could help someone.

    This is not an infinite loop, but when you get to the end of the thumbnail carousel and click on next it goes back with animation to the initial state, and if you're at the beginning and press the prev button it will move till the lasts thumbnail images.

    First You have to comment (or removed) all the lines of _toggleControls, in this way we avoid that the buttons in navigation get hiden.

    And then change the code of _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();
            } } ) );
    
        },
    
    0 讨论(0)
  • 2021-01-21 09:26

    Elastislide code has evolved and the above solution does not work. So I have developed my own solution.

    This code makes elastislide autoplay and when arrived at last slide it returns to the first slide to be more ergonomic than the infinite loop caroussel.

    This code should be added in the _initEvents function after 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 讨论(0)
提交回复
热议问题