jQuery: using callback functions in plugins

by gabrieleromanato

HTML

<div id="gallery">
    <div id="gallery-wrapper">
        <img src="https://lh5.googleusercontent.com/-JlR0ocCxkEA/T_sUDoIDqKI/AAAAAAAABCI/3D20U34uLew/s550/img13.jpg" alt="" />
        <img src="https://lh6.googleusercontent.com/-lNpz4tOXd9g/T_sUD3p7oOI/AAAAAAAABCI/tR10yDlM33U/s550/img14.jpg" alt="" />
        <img src="https://lh3.googleusercontent.com/-Sw5l3rSLzw0/T_sUEGHfIZI/AAAAAAAABCI/T8z_vjngGIs/s550/img15.jpg" alt="" />
        <img src="https://lh5.googleusercontent.com/-ChVkTowAPOw/T_sUEop_n8I/AAAAAAAABCI/RlpHJUgsdx8/s550/img16.jpg" alt="" />
    </div>
</div>

CSS

#gallery {
    width: 550px;
    margin: 2em auto;
    border: 1em solid #ddd;
    overflow: hidden;
}

#gallery-wrapper {
    position: relative;
    height: 330px;
}

#gallery img {
    float: left;
}

#gallery .page {
    display: inline-block;
    width: 2em;
    height: 2em;
    line-height: 2;
    background: #000;
    text-decoration: none;
    color: #fff;
    margin-right: 0.5em;
}

JavaScript

(function($) {

    $.fn.gallery = function(options) {
        var self = this;

        options = $.extend({
            wrapper: $('#gallery-wrapper', self),
            width: 550,
            height: 330,
            paginationClass: 'page',
            onimage: function() {}
        }, options);

        var images = $('img', self),
            length = images.length;

        var _setWrapper = function() {

            options.wrapper.width(options.width * length);

        }

        var _paginate = function() {

            var html = '<div id="gallery-pagination"/>';
            $(html).css({
                margin: '1em 0',
                textAlign: 'center'
            }).appendTo(self);

            for (var i = 0; i < length; i++) {

                $('<a/>').attr({
                    href: '#',
                    'data-image': i,
                    'class': options.paginationClass
                }).
                text(i + 1).
                appendTo('#gallery-pagination');

            }

        };

        var _navigate = function() {

            $('a', '#gallery-pagination').click(function(e) {

                e.preventDefault();
                var $a = $(this);
                var imageIndex = $a.data('image');
                var image = $('img', self).eq(imageIndex);
                var offset = image.position().left;
                options.wrapper.animate({

                    left: -offset

                }, 1500, 'linear', function() {

                    options.onimage(image);

                });

            });

        };

        return this.each(function() {

            _setWrapper();
            _paginate();
            _navigate();
        });

    };


})(jQuery);


$('#gallery').gallery({
    onimage: function(img) {
        img.animate({
            opacity: 0.5
        }, 1000);
    }
});