Carousel用JS管理状态和用CSS动画

时间:2014-08-07 07:17:04

标签: javascript jquery html css css3

这是我尝试使用css3创建旋转木马的第一次尝试,不太确定我是否正确操作,但它是一次尝试,此旋转木马只会在移动设备上显示。

正如我所理解的那样,JavaScript应该只用于管理状态,然后用CSS3来设置它的动画,所以我解释为基本上用js交换类并使用css3将转换放在这些类上。

我所知道的唯一真正的问题是实际的动画和状态管理,我需要它像无限/循环旋转木马一样动画,但由于某种原因我只是没有得到它。

这是JSFIDDLE DEMO

这是HTML:

<div class="vertical-list mobile-carousel">
    <div class="column active">
        <img src="http://placehold.it/200x200" class="circular-image" alt=""/>
        <p>
            <strong>Slide 1</strong><br>
            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Assumenda cumque dignissimos perspiciatis voluptas voluptatem!
            Ad debitis dignissimos doloribus exercitationem natus officiis quod sit, vitae voluptate. Alias debitis delectus exercitationem quia.
        </p>
    </div>
    <div class="column">
        <img src="http://placehold.it/200x200" class="circular-image" alt=""/>
        <p>
            <strong>Slide 2</strong><br>
            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Assumenda cumque dignissimos perspiciatis voluptas voluptatem!
            Ad debitis dignissimos doloribus exercitationem natus officiis quod sit, vitae voluptate. Alias debitis delectus exercitationem quia.
        </p>
    </div>
    <div class="column last">
        <img src="http://placehold.it/200x200" class="circular-image" alt=""/>
        <p>
            <strong>Slide 3</strong><br>
            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Assumenda cumque dignissimos perspiciatis voluptas voluptatem!
            Ad debitis dignissimos doloribus exercitationem natus officiis quod sit, vitae voluptate. Alias debitis delectus exercitationem quia.
        </p>
    </div>
    <a class="carousel-navigate next" href="#next">Next</a>
    <a class="carousel-navigate prev" href="#prev">Prev</a>
</div>

这是CSS:

.mobile-carousel .carousel-navigate {
  display: none;
}

  .mobile-carousel {
    position: relative;
    overflow: hidden;
  }
  .mobile-carousel .column {
    /*Start State*/
    background: red;
    width: 100%;
    float: left;
    margin-left: 0;
    margin-right: 0;
    display: inline-block;
    opacity: 0;
  }
  .mobile-carousel .column.active {
    /*Idle State*/
    opacity: 1;
    -moz-transition: all 0.3s;
    -o-transition: all 0.3s;
    -webkit-transition: all 0.3s;
    transition: all 0.3s;
  }
  .mobile-carousel .column.slide-in {
    /*Animate In*/
    opacity: 1;
    -moz-transition: all 0.3s;
    -o-transition: all 0.3s;
    -webkit-transition: all 0.3s;
    transition: all 0.3s;
  }
  .mobile-carousel .column.slide-out {
    /*Animate Out*/
    opacity: 0;
    -moz-transition: all 0.3s;
    -o-transition: all 0.3s;
    -webkit-transition: all 0.3s;
    transition: all 0.3s;
  }
  .mobile-carousel .carousel-navigate {
    position: absolute;
    top: 50%;
    display: block;
  }
  .mobile-carousel .next {
    right: 0;
  }
  .mobile-carousel .prev {
    left: 0;
  }

和Javascript:

;( function($, window, undefined) {
    'use strict';

    $.Carousel = function(element) {
        this.$el = $(element);
    };

    $.Carousel.prototype = {
        _init: function(){ //Init The Plugin
            this._layout();
            this._initEvents();
        },
        _layout: function(){ //Map the Layout of the Menu
            this.pages = this.$el.children( '.column' );
            this.pagesLength = this.pages.length;
            this.activePage = this.$el.children('.active');
            this.nextPage = this.$el.children('.next');
            this.prevPage = this.$el.children('.prev');

            //Set Some Layout Rules
//            this.pagesWrapper.width(100 * this.pagesLength+'%');
//            this.pages.width(100/this.pagesLength+'%');
        },
        _initEvents: function () { //Set Up the Event Listeners
            var self = this;
            this.nextPage.on('click.carousel', function(e) {
                self._page(+1);
                e.preventDefault();
            });

            this.prevPage.on('click.carousel', function(e) {
                self._page(-1);
                e.preventDefault();
            });
        },
        _page: function (delta) {
            var index = this.activePage.index() + delta,
                length = (this.pagesLength - 1);
            if(index < 0){
                index = length;
            }
            if(index > length){
                index = 0;
            }
            this._animatePage(this.activePage,$(this.pages.get(index)),delta);
        },
        _animatePage: function (active, target, direction){
            var self = this,
                direction_in = "",
                direction_out = "";

            if(direction > 1){
                direction_in = 'right';
                direction_out = 'left';
            }else{
                direction_in = 'left';
                direction_out = 'right';
            }

            this.activePage.addClass('slide-out '+direction_out); //Start Sliding Active Page Out
            target.addClass('slide-in '+direction_in); //Start Sliding Target Page In
            setTimeout(function() {
                //Remove Transition Classes from Active Page
                self.activePage.removeClass('active slide-out '+direction_out);

                //Change Active to Target Remove Transition Classes
                self.activePage = target;
                self.activePage.addClass('active').removeClass('slide-in '+direction_in);
            }, 300);
        }
    };

    $.fn.carousel = function() { //Create the Instance of the Menu
        var instance = $.data( this, 'carousel', new $.Carousel(this));
        this.each(function() {
            instance ? instance._init() : instance = $.data( this, 'carousel', new $.Carousel(this ) );
        });
        return instance;
    }
})(jQuery, window);

$(function() {
    $('.mobile-carousel').carousel();
});

任何帮助都会受到极大的赞赏。

1 个答案:

答案 0 :(得分:4)

执行此操作的简单方法可能是使用简单的setInterval() function

这样的事情:

<强> New and Improved Working Example

(function ($, window, undefined) {
    'use strict';

    $.Carousel = function (element) {
        this.$el = $(element);
    };

    $.Carousel.prototype = {

        _init: function () { //Init The Plugin
            this._layout();
            this._initEvents();
            this.autoPlay();

        },
        _layout: function () { //Map the Layout of the Menu
            this.pages = this.$el.children('.column');
            this.pagesLength = this.pages.length;
            this.activePage = this.$el.children('.active');
            this.nextPage = this.$el.children('.next');
            this.prevPage = this.$el.children('.prev');
        },
        autoPlay: function () {
            var self = this;
            var play = setInterval(function () {
                self._page(+1); // same as clicking next
            }, 3000); // every 3 seconds
            $('.mobile-carousel').hover(function () { // when mouse is over carousel
                clearInterval(play); // clearInterval to pause
            }, function () { // when mouse is not over carousel 
                play = setInterval(function () { // setInterval again to resume playing
                    self._page(+1);
                }, 3000);
            });
        },
        _initEvents: function () { //Set Up the Event Listeners
            var self = this;
            this.nextPage.on('click.carousel', function (e) {
                self._page(+1);
                e.preventDefault();
            });

            this.prevPage.on('click.carousel', function (e) {
                self._page(-1);
                e.preventDefault();
            });
        },
        _page: function (delta) {
            var index = this.activePage.index() + delta,
                length = (this.pagesLength - 1);
            if (index < 0) {
                index = length;
            }
            if (index > length) {
                index = 0;
            }
            this._animatePage(this.activePage, $(this.pages.get(index)), delta);
        },
        _animatePage: function (active, target, direction) {
            var self = this,
                direction_in = "",
                direction_out = "";

            if (direction < 1) {
/*changed*/     direction_in = 'left'; // swapped these
                direction_out = 'right';
            } else {
                direction_in = 'right'; // with these
                direction_out = 'left';
            }

            this.activePage.addClass('slide-out ' + direction_out); //Start Sliding Active Page Out
            target.addClass('slide-in ' + direction_in); //Start Sliding Target Page In
            setTimeout(function () {
                //Remove Transition Classes from Active Page
                self.activePage.removeClass('active slide-out ' + direction_out);

                //Change Active to Target Remove Transition Classes
                self.activePage = target;
                self.activePage.addClass('active').removeClass('slide-in ' + direction_in);
            }, 300);
        }
    };

    $.fn.carousel = function () { //Create the Instance of the Menu
        var instance = $.data(this, 'carousel', new $.Carousel(this));
        this.each(function () {
            instance ? instance._init() : instance = $.data(this, 'carousel', new $.Carousel(this));
        });
        return instance;
    };
})(jQuery, window);

$(function () {
    $('.mobile-carousel').carousel();
});

我重新设计了你的css,以防止旋转木马在页面上下跳跃,并使prev / next按钮处于正确的位置。还修复了左/右类,因此转换将在两个方向上起作用:

.mobile-carousel {
    position: relative;
    height:300px;
    overflow: hidden;
}
.mobile-carousel .column {
    /*Start State*/
    position: absolute;
    background: red;
    width: 100%;
    margin-left: 0;
    margin-right: 0;
    display: inline-block;
    opacity: 0;
}
.mobile-carousel .column.active {
    /*Idle State*/
    opacity: 1;
    left:0;
    -moz-transition: all 0.3s;
    -o-transition: all 0.3s;
    -webkit-transition: all 0.3s;
    transition: all 0.3s;
}
.mobile-carousel .column.slide-in.right, .mobile-carousel .column.slide-in.left {
    /*Animate In*/
    opacity: 1;
    -moz-transition: all 0.3s;
    -o-transition: all 0.3s;
    -webkit-transition: all 0.3s;
    transition: all 0.3s;
}
.mobile-carousel .column.slide-in.right, .mobile-carousel .column.slide-out.right {
    left:-105%;
}
.mobile-carousel .column.slide-in.left, .mobile-carousel .column.slide-out.left {
    left:105%;
}
.mobile-carousel .column.slide-out.left, .mobile-carousel .column.slide-out.right {
    /*Animate Out*/
    opacity: 0;
}
.mobile-carousel .carousel-navigate {
    position: absolute;
    top: 50%;
    display: block;
}
.mobile-carousel .next {
    right: 0;
}
.mobile-carousel .prev {
    left: 0;
}