HI there, quick advice please.
I am developing a photography website for a client and I want him to be able to click on an image in a list of thumbnails and that will bring up the bigger version of the image clicked on. I have achieved this in my own website here already, but I was wondering if there is a better way to do it - I don't want to use a plugin or anything like that, I want to code it myself.
On my website I had a thumbnail:

<div class="thumbnail">
                        	<a href="javascript:void(0);" class="full_image"><img src="images/faith_thumb_1.jpg" alt="" style="border:0" onClick="change_image('big_image_1')"></a>                        </div><!-- END OF thumbnail 1-->

passing a big image <img src="images/faith_full_1.jpg" alt="" style="display:none" id="big_image_1"> as a parameter to the script:

function change_image(image)
		{
					$("#" + image).hide();
					$(".box").hide();
					$(".overlay").hide();

					$(".overlay").show();
					$(".box").show("slow");
					$("#" + image).fadeIn(1000);
					$(".close_button").show();


				$(".close_button").click(function() {
					$(this).hide();
					 $("#" + image).fadeOut("fast");
					$(".box").hide("slow");
					$(".overlay").hide("slow");
				});
		}

which then did all the rest (and I got quite a bit of help with this, thanks again!!).
Now I wonder, is there a better, more efficient and easier way to do this or is it better if I stick to that in my other website? I just thought I will ask before starting to code - I have only coded the overlay so far
thanks

Hi Violet, I think it's a good way to do it, and it's quite fast. I did something similar myself.

But you can always improve your code, I suggest something like this:

var $box, $overlay, $closeButton;

$(function()
{
	// Get re-used jquery objects only at page load
	// It would be even better if used ID(faster)
	$box = $(".box");
	$overlay = $(".overlay");
	$close_button = $(".close_button");
});

function change_image(image)
{
	var $image = $("#" + image);
	
	$overlay.hide().show();
	$box.hide().show("slow");
	$image.hide().fadeIn(1000);	
	$close_button.show();

	$close_button.unbind('click').click(function() {
		$(this).hide();
		$image.fadeOut("fast");
		$box.hide("slow");
		$overlay.hide("slow");
	});
}

Good work.

Hi aleMonteiro, thanks for that.
A few questions about your code if I may ask, that is not clear to me.
That last bit:

$close_button.unbind('click').click(function() {
		$(this).hide();
		$image.fadeOut("fast");
		$box.hide("slow");
		$overlay.hide("slow");
	});

You have used the unbind method. I had a look at what that involves and I found that it is supposed to remove the handlers from the selector.
So that unbind method removes the click handler just from the $close_button doesn't it?
Also I will leave the thread open for a bit just in case I come across problems with that code
thanks

Violet, yes. It removes the handlers that the button has.

I did it because: every time the change_image() runs it adds a new click handler to the close_button, and when you click the button all handlers are executed.

Example: you open image one, close it and then open image two. When you close the image two it will actually try to close image one again(because the handler is still there).

If you open 10 images, when you close the last one, it would try and close all 10 again.

In your code this wasn't a problem, because the image one was already closed, so it won't do anything on the UI, but it still running and consuming memory.

This is a simple test page so you can see what really happens:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js" type="text/javascript"></script>
    <script type="text/javascript">  
        $(function(){
            var $btn1 = $("#myButton_1");
			var $btn2 = $("#myButton_2");
			
			$btn1
				.click(function() { // Adds handler 1
					alert("Handler 1");
				})
				.click(function() { // Adds Handler 2
					alert("Handler 2");
				});
				
			$btn2
				.click(function() { // Adds handler 1
					alert("Handler 1");
				})
				.unbind('click') // Unbinds handler 1
				.click(function() { // Adds Handler 2
					alert("Handler 2");
				});
        });
    </script>        
</head>
<body>
    <button id="myButton_1" type="button">No Unbind</button>
	
	<button id="myButton_2" type="button">Unbinded</button>
</body>
</html>

You're welcome.

thanks for the example.
I had a go at applying your code to my own site but it doesn't seem to work.
here's the script (might be worth mentioning that it is stored in an external file):

var $full_images;
var $close_button;
var $overlay;

$(function(){
	$full_images = $(".full_images");
	$close_button = $(".close_button");
	$overlay = $(".overlay");
});

function change_images(image){
		var image = $("#" + image);
		
		$overlay.hide().show();
		$full_images.hide().show("slow");
		$image.hide().fadeIn(1000);
		$close_button.hide().show();
		
		$close_button.unbind('click').click(function(){
			$(this).hide();
			$image.fadeOut("fast");
			$full_images.hide("slow");
			$overlay.hide("slow");
			
		});
		


}

Here's the relevant html:

...
<script type = "text/javascript" src = "javascripts/main_pix.js"></script>
...
<div class = "main_categories">

					<div class = "thumbnail_1">
						<a href="#"><img style="border: 0pt none;" alt="" src="images/travel_page/travels_boxes_1.jpg" onClick = "change_images('image1')"></a>
					</div><!--END OF thumbnail_1 -->

					<div class = "thumbnail_2">
						<a href="#"><img style="border: 0pt none;" alt="" src="images/travel_page/travels_boxes_1.jpg" onClick = "change_images('image2')"></a>
					</div><!--END OF thumbnail_2 -->

					<div class = "thumbnail_3">
						<a href="#"><img style="border: 0pt none;" alt="" src="images/travel_page/travels_boxes_1.jpg" onClick = "change_images('image3')"></a>
					</div><!--END OF thumbnail_3 -->
...

<div class = "full_images">
						<div class = "image_div">
							<img src = "images/animal_full_11.jpg" alt = "" id = "image1" style="display:none">
							<img src = "images/animal_full_12.jpg" alt = "" id = "image2" style="display:none">
							<img src = "images/animal_full_13.jpg" alt = "" id = "image3" style="display:none">
						</div><!--END OF image_div -->
						<div class = "close_button">
							<a href="javascript:void(0);"><img src = "images/button_9.gif" alt = "" style="border:0"></a>
						</div><!-- END OF close_button -->
					</div><!-- END OF full_images -->

			</div><!--END OF main_categories -->
...

And finally the css:

...
.overlay
	{

		display:none;
		background-color:black;
		position:fixed;
		opacity:0.75;
		filter:alpha(opacity=75); /* For IE8 and earlier */
		top:0;
		bottom:0;
		right:0;
		left:0;
		width:100%;
		z-index:100;

	} 
	
.full_images
	{
	
		display:none;
		background-color:black;
		position:fixed;
		width:700px;
		height:490px;	
		z-index:102;
		left:50%;
		top:50%;
		margin:-245px 0 0 -350px; 
	
	}
	
.image_div
	{
	
		border:1px solid transparent;
		width:660px;
		height:450px;
		margin:20px auto 0;
		z-index:101;
		/*no positioning so that I can centre the image*/
	}
	
.close_button
	{
		
		position:absolute;
		top:0;
		right:0;
	
	}
	
.main_categories
	{
		border:1px solid transparent; /* green*/
		width:1024px; /* 90% */
		min-height:600px;
		/*min-width:800px;*/
		margin:30px auto 0px;
	}
...

I have done a few tests changing the code, html and css here and there but I didn't get it to work. Basically as it is at the moment if you click on a thumbnail it brings up the various overlay, boxes and button, but not the image. Firebug says "$image is not defined
[Break On This Error] $image.hide().fadeIn(1000); ". Bearing in mind what I have learned here about passing parameters within functions from the html to the script, at the moment I am passing a string but even if I remove the quotes nothing happens. The main container .full_images the black box behind the big picture has a position fixed and z index of 102 while the image container .image_div which containes the images has 103. The images in the html have all displayed:none; because the jquery is supposed to display them. I notice that if I remove the style="display:none" from the big images in the html when I click on the thumbnail the script shows the picture but only the first one no matter which thumbnail I click on. Odd.

Also when I attempt to close the picture (well, which is not there) clicking the close button nothing happens.
I went through the code again but I can't spot the problem, any suggestion at all?

Violet,

you are using the '$image' var but you are creating with the name 'image'.

var image = $("#" + image); // This should be var $image
$image.hide().fadeIn(1000);

Fix this and see the result.

sorry that was one of the things I tried but nothing has happened:

var $full_images;
var $close_button;
var $overlay;

$(function(){
	$full_images = $(".full_images");
	$close_button = $(".close_button");
	$overlay = $(".overlay");
});

function change_images(image){
		var images = $("#" + image);
		
		$overlay.hide().show();
		$full_images.hide().show("slow");
		$images.hide().fadeIn(1000);
		$close_button.hide().show();
		
		$close_button.unbind('click').click(function(){
			$(this).hide();
			$images.fadeOut("fast");
			$full_images.hide("slow");
			$overlay.hide("slow");
			
		});
		


}

...solved...my fault as usual, I had missed a $.
Now that's really odd though. I wrote var images = $("#" + image); rather than var $images = $("#" + image); and all the script crumbled to pieces. I thought that the $ symbol is optional when you declare a variable!

Violet, '$' doesn't mean anything to the browser, it's just part of the variable name.

I only name the vars with $ so I can tell it's a JQuery object. But if you want to name it objImage, it's the same thing.

The problem was not the $, but the misspell of the var name.

One more though about your code: All images(thumbs and big) are loaded when the page loads. Because all images are created on the HTML.

So, if the big images that are not seen, are loaded.

If you wish to just load the viewed images: instead of creating one image tag for each big image, you need to create only one image and change the src with JS.

Instead of passing the id of the image to the change_image() you could pass the image url and then set it on the big image display.

Just an observation.

thanks for all your help aleMonteiro, much appreciated