Search code examples
javascriptjquerypluginsmultiple-instancesdefaults

Proper way to set default settings for each instance of jQuery plugin


I have been researching this for the past hour and I cannot seem to figure out what is wrong. I would like to make a simple plugin that allows for multiple instances each with their own settings I am not super versed in javascript so I am not using the object/prototype method.

When I run this plugin on two different elements, each with their own settings, only the last settings is being used as seen by the console.log

Here is what I have:

jQuery.fn.lighthouse = function(config) {

    config = $.extend({}, jQuery.fn.lighthouse.config, config);

    config.openDuration = config.openDuration || config.duration;
    config.closeDuration = config.closeDuration || config.duration;

    return this.each(function() {
        var containers = $(this);

        $(containers).click(open);
        $(config.closeSelector).click(close);

        console.log(config.contentType);

        $(containers).each(function() {
            if (config.contentType === 'img' && $(this).prop('tagName') === 'A') {
                var href = $(this).href,
                    src = $(this).children('img').src;
                if (href !== src) {
                }
            }
        });


        // Needs the container object
        function open(link) {
            link.preventDefault();
            var current = {
                close: $(this).children(config.closeSelector),
                background: $(this).children(config.backgroundSelector),
                container: $(this),
                child: $(this).children(config.childSelector)
            };

            console.log($(current.child).is(':hidden'));
            if($(current.child).is(':hidden')) {
                link.preventDefault();
            }

            $(current.container).append('<div class="background"></div>').css({
                background: config.background,
                width: '100%',
                height: '100%',
                position: 'fixed',
                zIndex: '2',
                opacity: config.backgroundOpacity,
                display: 'none'
            }).fadeIn(config.secondaryDuration);

            $(current.child).css({
                position: 'fixed',
                display: 'none',
                width: '150px',
                height: '150px',
                left: current.container.offset().left,
                top: current.container.offset().top,
                zIndex: '3'
            }).fadeIn(config.secondaryDuration).animate({
                width: '100%',
                height: '100%',
                top: '0',
                left: '0'
            }, config.openDuration, function () {
                $(current.container).append('<a class=".close">X</a>').css({
                    background: 'white',
                    color: 'black',
                    width: '50px',
                    height: '50px',
                    lineHeight: '50px',
                    textAlign: 'center',
                    position: 'absolute',
                    top: '0',
                    right: '0',
                    display: 'none'
                }).fadeIn(config.secondaryDuration);
            });

        }

        // Needs the close object
        function close(link) {
            link.preventDefault();

            var current = {
                close: $(this),
                background: $(this).siblings(config.backgroundSelector),
                container: $(this).parent(config.containerSelector),
                child: $(current.containter).children(config.childSelector)
            };

            $(current.close).fadeOut(config.secondaryDuration).remove();
            $(current.close).fadeOut(config.secondaryDuration).remove();

            $(current.child).animate({
                height: current.containter.height(),
                width: current.containter.width(),
                top: current.containter.offset().top,
                left: current.containter.offset().left
            }, config.closeDuration, function () {
                $(current.child).animate({
                    opacity: '0',
                }, config.secondaryDuration).css({
                    display: 'none',
                    zIndex: 'auto'
                });
            });
        }
    });
}

jQuery.fn.lighthouse.config = {
    containerSelector: '.lighthouse',
    childSelector: 'div',
    closeSelector: '.close',
    backgroundSelector: '.background',
    captionSelector: '.caption',
    duration: 350,
    openDuration: null,
    closeDuration: null,
    secondaryDuration: 100,
    background: 'rgb(230, 230, 230)',
    backgroundOpacity: '0.7',
    contentType: 'img'
}

This is what I am calling it with:

$('.image').lighthouse();
$('.click').lighthouse({
    childSelector: '.site',
    contentType: 'html'
});

Here is the jsfiddle: http://jsfiddle.net/yK9ad/

The proper output of console.log should be:

img
html

Any ideas? Thanks in advance for the help!


Solution

  • I think you are missing the class attribute for the anchor containing <img/> tag. Please see below

    <a class="image" href="http://placehold.it/900x800&text=Image">
        <img src="http://placehold.it/300x200&text=Image" />
        <span class="caption">
            test
        </span>
    </a>
    

    The updated fiddle - http://jsfiddle.net/yK9ad/2/

    I could see the following in the console.

    img
    html