views:

38

answers:

2

I want to show a big Image when I press the small thumbnail. A simple Lightbox style script.

When I press the grey transparent overlay area around the image, the CSS and image is removed from view. This code is stripped down. Maybe missed something needed...

$(document).ready(function() {    
    $(".lightBobo").click(function(e) {
        e.preventDefault();  // prevent to open link in new window
        $(this).lightBobo();
    });
});

jQuery.fn.lightBobo = function(e) {
    if (e != undefined)
        e.preventDefault();

    return this.each(function() {
        var img = new Image();

        $(img).load(function() {
            imgW = img.width;
            imgH = img.height;

            var overlay = $("<div />");
            var container = $("<div />");
            // Lots of css styling for <div> overlay and container image...

            container.append(img); //add image to div
            $("body").append(overlay); //add overlay to body
            $("body").append(container); //add div to body
            overlay.fadeIn("fast", function() {
                container.show();
            });
            $(overlay).click(function() {
                removeDivs();
            });
            function removeDivs() {
                container.hide();
                overlay.fadeOut("fast");
                img = null;
                container = null;
                overlay = null;
                openImgSrc = "";
            }
        });
    });
}

The problem is IE(7) is not showing the image the second time I want to show it. I have to do a page reload to display the image again. It works in FF though.

When I use FireFox I can see in FireBug that the get appended to for each time I show the big image. And the "old" image get's display: none; After 20 times I show the big image, I have 40 elements of Overlay and Container(image).

I can't figure out how to rerun the lightBobo function when needed. So it workes in both IE and FF.

+2  A: 

You should probably append the overlay and container just once when initialized, then just show/hide/append content when the user activates the modal.

Otherwise you need to do .remove() on each element ( = null is not enough ) when unloading, unless you want lots of dupes in the DOM.

I would do something like this:

(function($) {

var lightBobo = {
    init: function() {
        var self = this;
        this.overlay = $('<div>').click(this.hide); // bind the click event just once
        this.container = $('<div>');
        // apply id's or styling
        $(document.body).append(overlay,container);
    }
    hide: function(e) {
        lightBobo.container.hide();
        lightBobo.overlay.fadeOut('fast');
    },
    show: function() {
        var img = new Image();
        $(img).load(function() {
            imgW = img.width;
            imgH = img.height;
            lightBobo.container.append(img); //add image to div
            lightBobo.overlay.fadeIn("fast", function() {
                lightBobo.container.show();
            });
        });
    }
};

$(function() {
    lightBobo.init(); // init the lightbox once
});

$.fn.lightBobo = function() {
    return this.each(function() {
        lightBoo.show.apply(this);
    });
}

})(jQuery);


// bind the anchors here:

$(document).ready(function() {
    $(".lightBobo").click(function(e) {
        e.preventDefault();  // prevent to open link in new window
        $(this).lightBobo();
    });
});
David
That could be a good suggestion! Thank you for pointing out a possible solution! I unfortunatly found something that made my code work myself. =)
Niike2
A: 

I have found a solution. I changed lots of code. Specially the $(img).load(function() { ... } where I was having some problems. I dont really know WHY the load() function didnt want to kick the event more than one time. So I removed most code out of that function.

Remember the $(img).load(function() { ... } is for loading the image BEFORE finding its width and height. otherwise its 0.

$(document).ready(function() {

    $(".lightBobo").click(function(e) {
        if (e != undefined)
            e.preventDefault();
        $(this).lightBobo();
    });
});

jQuery.fn.lightBobo = function(e) {
    return this.each(function() {

        var myClickedObj = $(this);
        //check if we have a anchor or image tag
        var src = "";
        if (this.tagName.toLowerCase() == "a")
            src = this.href.toLowerCase();
        else if (this.tagName.toLowerCase() == "img")
            src = this.src.toLowerCase();
        else
            return;

        var winW = $(window).width();
        var winH = $(window).height();
        var docH = $(document).height();
        if (docH < winH)
            docH = winH;

        //the semitransparant overlay over the whole page
        var overlay = $("<div />")
            .attr("class", "bobOverlay") //used as id for closing all overlays
            .css("background", "#000")
            .css("opacity", "0.8")
            .css("display", "none")
            .click(function() { hideAll(); })

        $("body").append(overlay); //add overlay to body

        var loadLeft = (winW / 2) - (100 / 2);
        var loadTop = (winH / 2) - (20 / 2) + $(document).scrollTop();

        overlay.fadeIn("fast");

        //an element to hold our picture
        var container = $("<div />");
        container.attr("class", "bobOverlay");
        container.hide();

        var img = new Image();
        $(img).load(function() {
           var imgW = img.width;
           var imgH = img.height;

           container.append(this); //add the picture to the container
       $("body").append(container); // add container to the body
           container.fadeIn("fast"); //show container
       })
   .attr("src", src); //add the src to the image

        function hideAll() {
            $(".bobOverlay").fadeOut("fast");
        }
        function IsImage(filename) {
            var ext = filename.split('.').pop().toLowerCase();
            var allow = new Array("gif", "png", "jpg", "jpeg", "bmp");
            if (jQuery.inArray(ext, allow) == -1) {
                return false;
            }
            return true;
        }
    });
}

Sorry for the long code. And finding out the answer myself...

Niike2
Always good to add the answer if you found it yourself, helps out those of us who will defn encounter this problem tomorrow, haha. Also, I believe the issue with .load only being called once has to do with the browser cache... this is from the jQuery docs: "It is possible that the load event will not be triggered if the image is loaded from the browser cache. To account for this possibility, we can use a special load event that fires immediately if the image is ready. event.special.load is currently available as a plugin."
Java Drinker
Yes I was thinking about that problem. I found some suggestions that you can enter a Math.Random() number to the ID so you never get the browser to find it is already in Cache. Or specificly set Cache to a past date so every time its loaded. The browser needs the new version. Havent tried that though.
Niike2