Hi all, I am in the process of redoing my website and I have done pretty much all the html and css for it (http://antobbo.webspace.virginmedia.com/photogallery/test/home.htm), so now I would like to add some javascript/jquery.
This is essentially what I would like to achieve. On this page http://antobbo.webspace.virginmedia.com/photogallery/test/gloom.htm I have a series of thumbnails: when I click on a thumbnail I would like a much bigger picture to come up in the middle of the page on the top of the thumbnails. The window with the big picture will effectively overlap the thumbnails and will have the picture on it + a "close" button, so something like this http://fancybox.net/ (if you click on one of the picture in the example you will see what I mean).
Now, I know that there are many many plugins and etc to use, but I would like to do my own because I want to learn to use jquery and javascript (which I have used already in the past although I am not terribly good at it).
A web developer friend of mine gave me some good suggestions:
-to achieve this use 3 layers (he said to play a bit with the z-index). The first layer will shade the content on the page with the thumbnail, creating some sort of shade effect, the second layer will have the big picture and the third layer will have the button which will close the 3 layers and go back to my thumbnail page.

Can anybody suggest how should I start this (maybe if anybody knows a good place where I can find this kind of image gallery tutorial it would be great).
Also I am not 100% sure how the z-index will work with the css, as in if I use 3 layers how should I position them? I am not looking for code, but just for suggestion please on how to tackle this and maybe things I haven't thought about: - )
thanks

Recommended Answers

All 13 Replies

I'd suggest that you first create the HTML and CSS of the image displayer(the 3 layers your friend told you about).

When the look is the way you want, you hide it(display: none; for example) and then start playing with JS e JQuery to open the displayer and set the image that should be displayed.

I'd also use JS to center vertically the image displayer on the browser.

Good luck.

Hi AleMonteiro,
thanks for that.
I have created everything now and even attempted a bit of jquery, but I am having few problems with that.
First thing, here is what my jquery does http://antobbo.webspace.virginmedia.com/photogallery/test/water.htm (click on the first image to see).
Now let's see the code:
-jquery

<script type="text/javascript">

		$(function() {
			$("a.full_image").click(function() {
				$(".overlay").show();
				$(".box").show("slow");
				$(".standalone_image").fadeIn(4000);
				$(".close_button").show();			
			});
			
			$(".close_button").click(function() {
				$(this).hide();
				$("standalone_image").fadeOut("fast");
				$(".box").hide("slow");
				$(".overlay").hide("slow");
			});
			
		});

		</script>

-HTML:

<body>
    
         <div class="overlay" id="overlay" ><!-- BOX FOR THE OVERLAY-->                
         </div><!-- END OF THE OVERLAY-->
         
         <div class="box" id="box"><!-- BOX FOR THE IMAGE -->   
         	
			<div class="standalone_image"><!-- BOX FOR THE IMAGE-->
            </div><!-- END OF BOX FOR THE IMAGE-->
            
           	  
             <div class="close_button" id="close_button"><!-- BOX FOR THE CLOSE BUTTON -->
             </div><!-- END OF BOX FOR THE CLOSE BUTTON -->
               	
         </div><!--END OF BOX FOR THE IMAGE -->
...
<div class="thumb_container">
                
                        <div class="thumbnail">  
                        	<a href="#" class="full_image"><img src="images/water_thumb_1.jpg" alt="" style="border:0"></a>                  
                        </div><!-- END OF thumbnail 1-->
                    
                        <div class="thumbnail">    
                        	<a href="#" class="full_image"><img src="images/water_thumb_2.jpg" alt="" style="border:0"></a>               
                        </div><!-- END OF thumbnail 2-->
....

-CSS:

/* FOR THE IMAGES POP UP WINDOW */
.overlay
{
	display:none;
	background:#cf1dbb;
	opacity:0.85;
	filter:alpha(opacity=85); /* For IE8 and earlier */
	top:0px;
	bottom:0px;
	left:0px;
	right:0px;
	position:fixed;
	z-index:100;	
}

.box
{
	display:none;
	background-color:black;
	width:660px;
	height:450px;
	position:absolute;
	right:30%;
	left:30%;
	top:10%;
	z-index:101;
}

.standalone_image
{
		display:none;
		background:url(../images/water_full_3.jpg) no-repeat;
		position:absolute;
		z-index:101;
		width:602px;
		height:399px;
		top:25.5px;
		bottom:25.5px
		left:29px;
		right:29px;
		/*border:1px solid red;*/
	
}

.close_button
{	
	display:none;
	left:94%;	
	background:url(../images/close_button.png);
	width:40px;
	height:40px;
	position:absolute;
	z-index:102;
}

Now let's get to the problems I am having:
1)the thumbnails are actually links to nowhere <a href="#" class="full_image"><img src="images/water_thumb_1.jpg" alt="" style="border:0"></a> and somehow this causes a problem to the pop up image: if you try the first image in the link provided, then close the overlay window and click on the second thumbnail, the url still stays on the "#" link and the image fade in effect is lost. Is there an accessible alternative to the "#" link? The thing is I don't know what the thumbnail can link to.

2)at the moment I am using only a big picture to test my jquery but I wonder how do I make sure that each thumbnail when clicked actually displays the right picture. At the moment 2 different thumbnails display the same picture. One way to get around this is to make sure that each thumbnail when click invokes a different jquery script but it is not feasible - incidentally this is what I have done in my old website http://antobbo.webspace.virginmedia.com/photography/water.htm and the script is
unmanageable and I don't want to make the same mistake again - because I will end up with hundreds of scripts. The alternative I suppose is to pass somehow the name of the picture to the script depending on which thumb you click on, but I can't think of how to do that.

3)the close button on the top right corner of the image: it is not a link, as in if you hover on with the mouse pointer the cursor doesn't change to a link. SHould I use CSS to change it, or is that not the best option?

Considering this is only the second time I use jquery could somebody possibly have a look at the code and tell me what it is that I can do to sort these problems out?
thanks a lot

Let's see the problems:

1. You don't have to use an <a href="#">, you can set the click directly on the image.

2. You have to got the url of the thumbnail clicked and then set it on the stand alone image.

3. Use the css property cursor: pointer.

Your JQuery could be something like this:

<script type="text/javascript">

		$(function() {
			$("img.full_image").click(function() {
                                var urlImg = $(this).attr("src");
				$(".overlay").show();
				$(".box").show("slow");
				$(".standalone_image").css("backgroundimg", "url('" + urlImg + "')") .fadeIn(4000);
				$(".close_button").show();			
			});
			
			$(".close_button").click(function() {
				$(this).hide();
				$("standalone_image").fadeOut("fast");
				$(".box").hide("slow");
				$(".overlay").hide("slow");
			});
			
		});

		</script>

and the thumb html:

<div class="thumbnail">  
     <img  class="full_image" src="images/water_thumb_1.jpg" alt="" style="border:0">
</div>

Hi AleMonteiro,
thanks for that.
I have done a bit more work and I think I resolved problem 1 in a different way: rather than using "#" I will have something like

<a href="javascript:void(0);" ><img src="images/water_thumb_1.jpg" alt="" style="border:0" class="full_image"></a>

If I simply change the css property cursor and set the click directly on the image, then yes, the mouse cursor will change but the element is not a link, whereas with the

javascript:void

we are sure that the element is a link - and a good thing of that is that when you click on a thumbnail at the bottom of the page the focus stays there and doesn't go all the way up the page again.

About the jquery, thanks for that, it's great. One thing though that I am a bit unsure of. Say I make the above change to the link, then I can have:

$(function() {
			$("a.full_image").click(function() {
				  var urlImg = $("img.full_image").attr("src");
				$(".overlay").show();
				$(".box").show("slow");
				$(".standalone_image").css("backgroundImage", "url('" + urlImg + "')") .fadeIn(4000);
				$(".close_button").show();			
			});
			
			$(".close_button").click(function() {
				$(this).hide();
				$("standalone_image").fadeOut("fast");
				$(".box").hide("slow");
				$(".overlay").hide("slow");
			});
			
		});

I might be wrong but shouldn't your "backgroundimg" be "backgroundImage"?
Also, could you please explain me this line "url('" + urlImg + "')") , why do we need that many quotes?

In the css I can leave everything as it is I believe
thanks again

AleMonteiro,
looking again at your code I realize that it might not work because with your code I will replace the big picture with the image in the thumbnail. So your script is saying, if I am not mistaken:
when the thumbnail is clicked on save the URL of the thumbnail image in the variable urlImg , then all the rest of the code and then select standalone_image and change its background image from what it is to the content of the urlImg variable which has the url of the thumbnail and not the URL of the full image, so it won't work...or am I saying sth silly (sorry I have been in from of the monitor for over 9 hrs today doing this!)

Violet 82, you are right about the url. In this way the url of the full image will be the same of the thumb.

To overcome that you need to store the full image url in somewhere. There a lot of ways you can do it: Store in some non-using attribute, create some new attribute like bigImageSrc(in XHTML), use an input hidden, javascript array, jquery.data and etc.

I made an example with alt non-using attribute and input hidden.

<script>
		$(function() {
		
			$("a.full_image").click(function() {
				var $img = $(this).children("img");
				var urlImg = $img.attr("src"); // thumbnail src
				urlImg = $img.attr("alt"); // big src from alt attr
				urlImg = $(this).children("input").val(); // big image from input hidden 
				
				$(".overlay").show();
				$(".box").show("slow");
				$(".standalone_image").css("background-image", "url(" + urlImg + ")") .fadeIn(4000); // works
				$(".standalone_image").css("background", "url('" + urlImg + "')") .fadeIn(4000); // works as well
				$(".close_button").show();			
			});
			
			$(".close_button").click(function() {
				$(this).hide();
				$("standalone_image").fadeOut("fast");
				$(".box").hide("slow");
				$(".overlay").hide("slow");
			});
		});
	
	</script>
	

	<body>

         <div class="overlay" id="overlay" ></div>
         
         <div class="box" id="box">
         	
			<div class="standalone_image"></div>
           	  
             <div class="close_button" id="close_button"></div>
               	
         </div>

		<div class="thumb_container">                
			<div class="thumbnail">  
				<a href="#" class="full_image">
					<img src="images/water_thumb_1.jpg" alt="images/water_thumb_1_big.jpg" style="border:0">
					<input type="hidden" value="images/water_thumb_1_big.jpg" />
				</a>
			</div>
		
			<div class="thumbnail">    
				<a href="#" class="full_image">
					<img src="images/water_thumb_2.jpg" alt="images/water_thumb_2_big.jpg" style="border:0">               
					<input type="hidden" value="images/water_thumb_1_big.jpg" />
				</a>
			</div>
		</div>
	</body>

Hi AleMonteiro,
thanks for posting the code, although I am not entirely sure I understand the way you are using the alt attribute and the various .children() in the jquery.
I made some changes to my code, hoping to find an easy solution...but I think I didn't : (

Basically, here's what I have done.
HTML:

...
<div class="thumbnail">
<a href="#" class="full_image"><img src="images/water_thumb_1.jpg" alt="" style="border:0" onClick="change_image('big_image_1')"></a>
<img src="images/water_full_1.jpg" alt="" style="display:none" id="big_image_1">
</div><!-- END OF thumbnail 1-->

<div class="thumbnail">
<a href="#" class="full_image"><img src="images/water_thumb_2.jpg" alt="" style="border:0" onClick="change_image('big_image_2')"></a>
<img src="images/water_full_3.jpg" alt="" style="display:none" id="big_image_2">
</div><!-- END OF thumbnail 2-->
...

So if we take the first "thumbnail" div, I have my thumbnail picture "images/water_thumb_1.jpg" in it which when clicked on will pass the id (big_image_1) of the full picture "images/water_full_1.jpg", which is currently hidden,
to the javascript function "change_image" and jquery script modified as below:

<script type="text/javascript">

function change_image(image)
{

$(function() {

$(".overlay").show();
$(".box").show("slow");
$(image).fadeIn(4000);
$(".close_button").show();


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

});
}
</script>

The picture passed as a variable (image) will be then used to display the big picture
The script is meant to be firing up few boxes (an overlay, a box where the big picture will be displayed in and a close button, as before).
Here are the slightly amended css for the various boxes:

...
/* FOR THE IMAGES POP UP WINDOW */
.overlay
{
display:none;
background:#cf1dbb;
opacity:0.85;
filter:alpha(opacity=85); /* For IE8 and earlier */
top:0px;
bottom:0px;
left:0px;
right:0px;
position:fixed;
z-index:100;
}

.box
{
display:none;
background-color:black;
width:660px;
height:450px;
position:absolute;
right:30%;
left:30%;
top:10%;
z-index:101;
}

.standalone_image
{
display:none;
/*background:url(../images/water_full_3.jpg) no-repeat;*/
position:absolute;
z-index:101;
width:602px;
height:399px;
top:25.5px;
bottom:25.5px
left:29px;
right:29px;
/*border:1px solid red;*/

}

It might be better if you view sources though.

So essentially, I didn't put the big images in an array as you suggested, I simply put them in the thumbnail div and hid them. I thought this was the easiest way to do it, but then somehow the id I pass to the function doesn't seem to be working...am I passsing it in a dodgy way, or am I completely going crazy?!
thanks for your help again

Violet, your code won't work cause you can't use $(function(){}) inside an function.

$(function(){}) is a shortchut to window.onload event, so if you put it inside another function it won't be executed.

Also, the param you recieve in the changeImage function is a string, so you would need to get the element by that id.

To your function to work it should be something like this:

function change_image(image)
{
    $(".overlay").show();
    $(".box").show("slow");
    $("#" + image).fadeIn(4000);
    $(".close_button").show();
 
    $(".close_button").click(function() {
        $(this).hide();
        $("#" + image).fadeOut("fast"); // You need to close the opened image now
        $(".box").hide("slow");
        $(".overlay").hide("slow");
    });
});
}

But let me explain my code, i've ajusted to your new html with hidden full image:

// Set on document ready/window onload event
		$(function() {
			// Set click listener on <a>
			$("a.full_image").click(function() {
				
				// $(this) is the <a> element clicked
				var $imgThumb = $(this).children("img"); // Get the <img> element inside the <a>
				var $imgFull = $(this).next("img"); // Get the next <img> element besides <a>
				
				var urlThumb = $imgThumb.attr("src"); // Get the src attribute from the thumb <img>
				var urlFull = $imgFull.attr("src"); // Get the src attribute from the full <img>
				
				$(".overlay").show();
				$(".box").show("slow");
				$(".standalone_image").css("background", "url('" + urlFull + "')") .fadeIn(4000);
				$(".close_button").show();			
			});
			
			$(".close_button").click(function() {
				$(this).hide();
				$("standalone_image").fadeOut("fast");
				$(".box").hide("slow");
				$(".overlay").hide("slow");
			});
		});

Hi AleMonteiro,
thanks for that, now it is much clearer. For my website I think I will use my script simply because I find it easier :). That said, I find your script much more interesting than mine, and it was really kind of you to add the comments, so now I understand how that works.
Let's start with your script first.
It is all pretty much clear apart few minor things and I am referring to the "img" element and "scr" attribute. In short why do we need to get both "img" and "src", can we not just get the src attribute directly and use it in the script? Or is it something like "we need to get "img" in order to extract "src"? What really counts is the "src" that allows us to change the picture url so why do we need the "img" for?
The methods to get them are clear enough, it's just the reason why we do that really.
I looked up the .next() and .children() methods for more examples, and I really like the how easier is to use them to navigate through the DOM tree. The thing is that I simply didn't know I could use those methods...I have got a lot to learn!

Also I had some problems getting my head around all the quotes around this "url('" + urlFull + "')" . The external quotes are fine, they are part of the syntax but the ones in the brackets ('" + urlFull + "') , what are they suppose to mean?

Let's get quickly to my script.
I didn't know that the document.ready function couldn't be inside another function, apologies. SOmething that really bugged my about that script was the fact that I couldn't use the variable "image" that I passed to the function, I guess because I was using it in the wrong way, I was doing something like $(image).fadeOut()... whereas I can see that the correct way is $('#'+image).fadeOut()...Is this the standard way to use variable as selectors, as in do I have to have '#'+ before them?

To make that script work I had to change the html slightly so now the big pictures sit somewhere else in the code (I haven't updated the live site, just the local copy):

...
<div class="standalone_image"><!-- BOX FOR THE IMAGE-->
            <img src="images/water_full_1.jpg" alt="" style="display:none" id="big_image_1">
            <img src="images/water_full_3.jpg" alt="" style="display:none" id="big_image_2">
            </div><!-- END OF BOX FOR THE IMAGE-->
...

the thumbnail divs are still pretty much the same

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

the css's are the same, now I only need to find a way to make sure that the box with the picture actually stays in the middle of the page even if the browser window is resized (that's not happening at the moment)
thanks

Violet,

about the img and src: The src is a property of the img element, so we must first find the img element to be able to get it's src. In my code I first create a variable for the img just to make the code more understandable, but we can do it all at once:

var url = $(this).children("img").attr("src");

About the quotes: it's not necessary, it's just a code pattern I use. In css we can use both url(path) and url('path'). So we can do the same in JS. If you think it's better, just cut off those things.

About the .children() and .next(): JQuery has a lot of good methods to find DOM elements. Those are just a couple, but there is a lot more, like: .find(), .parent(), .siblings(), .closest() and etc.

JQuery documentation is great for discovering those methods, and it has a lot of samples and usage example.


Now about your code:

When you use onClick="change_image('big_image_2')" you are calling the function passing the string "big_image_2" as parameter. I mean, you are sending a string not an object. That's why you need to get the object. But you can pass the object directly.

change_image('big_image_2') // The quotes means it's a string
change_image(big_image_2) // Without the quotes you are referring to the object witch the ID is big_image_2

About centering the image: If you always want to keep the image on the center you need to listen to the windows resize event. This way you'll know when the window was resized and then you can re-calculate the image position. Again, JQuery make this very easy for us:

// document ready
$(function()
{
    // Set the resize listener 
    $(window).resize(function()
    {
        document.write("window resized");
    });
});

You are welcome.

Hi AleMonteiro, cool thanksm now I understand all your code.
About the resizing business, in your code I suppose I will have to get the coordinates of the box and then change them correct?
I have noticed a little problem with my script in IE6 but I think I will start a new thread for that because it is about compatibility, so maybe not a good idea to mix it with all the rest

Violet, yes. You have to calculate the coordinates and set it to the image.

And yes, it's better to start a new tread about the compatibility issue.

Please mark as solved if you don't have any more doubt about the subject.

Good luck.

sure will do thanks for all your help much appreciated!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.