Смешивание данных плагина jQuery с несколькими экземплярами - PullRequest
2 голосов
/ 14 февраля 2012

Я пытаюсь разработать плагин jQuery для отображения адаптивных галерей изображений.Я использую .data () для хранения информации для каждого слайда галереи.

Кажется, что все работает нормально при отображении одной галереи, но смешивается при попытке создать несколько экземпляров галереи наодна страница. Грубую демонстрацию можно посмотреть здесь .

Вот код, который запускается:

(function($) {
    $.Gallery = function(element, options) {
        this.$el = $(element);
        this._init(options);
    };

    $.Gallery.defaults = {
        showCarousel : true,
    };

    $.Gallery.prototype = {
        _init : function(options) {
            var $this = $(this);
            var instance = this;

            // Get settings from stored instance
            var settings = $this.data('settings');
            var slides = $this.data('slides');

            // Create or update the settings of the current gallery instance
            if (typeof(settings) == 'undefined') {
                settings = $.extend(true, {}, $.Gallery.defaults, options);
            }
            else {
                settings = $.extend(true, {}, settings, options);
            }
            $this.data('settings', settings);

            if (typeof(slides) === 'undefined') {
                slides = [];
            }
            $this.data('slides', slides);

            instance.updateCarousel();
        },

        addItems : function(newItems) {
            var $this = $(this),
                slides = $this.data('slides');

            for (var i=0; i<newItems.length; i++) {
                slides.push(newItems[i]);
            };
        },

        updateCarousel : function() {
            var instance = this,
                $this = $(this);
                slides = $(instance).data('slides');

            var gallery = instance.$el.attr('id');

            /* Create carousel if it doesn't exist */
            if (instance.$el.children('.carousel').length == 0) {
                $('<div class="carousel"><ul></ul></div>').appendTo(instance.$el);
                var image = instance.$el.find('img');
            };

            var carouselList = instance.$el.find('.carousel > ul'),
                slideCount = slides.length,
                displayCount = carouselList.find('li').length;


            if (displayCount < slideCount) {
                for (var i=displayCount; i<slides.length; i++) {                    
                    slides[i].id = gallery + '-slide-' + i;
                    slide = $('<img>').attr({src : slides[i].thumb}).appendTo(carouselList).wrap(function() {
                        return '<li id="' + slides[i].id + '" />'
                    });

                    slide.on({
                        click : function() {
                            instance.slideTo($(this).parent().attr('id'));
                        },
                    });
                };
            };
        },

        slideTo : function(slideID) {
            var $this = $(this);
            var slides = $this.data('slides');
            var image;
            var $instance = $(this.$el);

            $(slides).each( function() {
                if (this.id == slideID){
                    image = this.img;
                };
            });

            $('<img/>').load( function() {
                $instance.find('div.image').empty().append('<img src="' + image + '"/>');
            }).attr( 'src', image );
        },
    };

    $.fn.gallery = function(options) {

        args = Array.prototype.slice.call(arguments, 1);

        this.each(function() {
            var instance = $(this).data('gallery');

            if (typeof(options) === 'string') {
                if (!instance) {
                    console.error('Methods cannot be called until jquery.responsiveGallery has been initialized.');
                }
                else if (!$.isFunction(instance[options])) {
                    console.error('The method "' + options + '" does not exist in jquery.responsiveGallery.');
                }
                else {
                    instance[options].apply(instance, args);
                }
            }
            else {
                 if (!instance) {
                    $(this).data('gallery', new $.Gallery(this, options));
                }
            }
        });
        return this;
    };

})(jQuery);

$(window).load(function() {
    $('#gallery2').gallery();
    $('#gallery3').gallery();

    $('#gallery2').gallery('addItems', [
        {
            img: 'images/image2.jpg',
            thumb: 'images/image2_thumb.jpg',
            desc: 'Image of number 2'
        },
        {
            img: 'images/image3.jpg',
            thumb: 'images/image3_thumb.jpg',
            desc: 'Image of number 3'
        },
        {
            img: 'images/image4.jpg',
            thumb: 'images/image4_thumb.jpg',
            desc: 'Image of number 4'
        },
        {
            img: 'images/image5.jpg',
            thumb: 'images/image5_thumb.jpg',
            desc: 'Image of number 5'
        }
    ]);

    $('.pGallery').gallery('addItems', [
        {
            img: 'images/2.jpg',
            thumb: 'images/2_thumb.jpg',
            desc: 'Image of number 0'
        },
        {
            img: 'images/image1.jpg',
            thumb: 'images/image1_thumb.jpg',
            desc: 'The second image'
        }
    ]);
    $('.pGallery').gallery('updateCarousel');
});

На поверхности кажется, что создаются две галереи с правильнойструктура слайдов:

  • gallery2
    • gallery2-slide-0
    • gallery2-slide-1
    • gallery2-slide-2
    • gallery2-slide-3
    • gallery2-slide-4
    • gallery2-slide-5
  • gallery3
    • gallery3-slide-0
    • gallery3-slide-1

Однако действие onclick не работает для двух последних слайдов Gallery2 (дублированные слайды)в обеих галереях).При ближайшем рассмотрении DOM я вижу, что слайды, хранящиеся в данных для gallery2, имеют следующие идентификаторы:

  • gallery2
    • gallery2-slide-0
    • gallery2-slide-1
    • gallery2-slide-2
    • gallery2-slide-3
    • gallery3-slide-0
    • gallery3-slide-1

Я не уверен, что вызывает путаницу или как ее исправить, поэтому любая помощь будет принята с благодарностью.Спасибо

1 Ответ

0 голосов
/ 14 февраля 2012

Ваша проблема в том, что вызов $('.pGallery').gallery('addItems'... приводит к тому, что одни и те же объекты добавляются во внутреннюю структуру обеих галерей, когда вы вызываете $('.pGallery').gallery('updateCarousel'); идентификаторы, хранящиеся в этих объектах, перезаписываются.

Вам нужно положить туда оригиналы. Есть:

addItems : function(newItems) {
    var $this = $(this),
        slides = $this.data('slides');

    for (var i=0; i<newItems.length; i++) {
        //slides.push(newItems[i]);
        slides.push(jQuery.extend({}, newItems[i]));
    };
},

С помощью jQuery.extend({}, oldObject) вы можете выполнить поверхностное копирование ;

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...