Jump to content

Image gallery, modal opens only for first image


hariskar

Recommended Posts

I made a responsive gallery and would like to open modal windows for each photo. My problem is that the modal opens only for the first image.

Any help please?

Thank you!

<div class="img">
     <img id="myImg" src="aithousa_anamonis_1.jpg" alt="Αίθουσα αναμονής 1" width="300" height="200">
</div>
<div class="img">
    <img id="myImg" src="aithousa_anamonis_2.jpg" alt="Αίθουσα αναμονής 2" width="300" height="200">
</div>
<div class="img">
     <img id="myImg" src="aithousa_anamonis_3.jpg" alt="Αίθουσα αναμονής 3" width="300" height="200">
</div>

<!-- The Modal -->
<div id="myModal" class="modal">
  <span class="close">×</span>
  <img class="modal-content" id="img01">
  <div id="caption"></div>
</div>

<script>
// Get the modal
var modal = document.getElementById('myModal');

// Get the image and insert it inside the modal - use its "alt" text as a caption
var img = document.getElementById('myImg');
var modalImg = document.getElementById("img01");
var captionText = document.getElementById("caption");
img.onclick = function(){
    modal.style.display = "block";
    modalImg.src = this.src;
    captionText.innerHTML = this.alt;
}

// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];

// When the user clicks on <span> (x), close the modal
span.onclick = function() {
    modal.style.display = "none";
}
</script>
Edited by hariskar
Link to comment
Share on other sites

IDs have to be unique, you can't have three elements with the same ID. The ID is supposed to identify a single element on the page.

 

If you want to reference multiple elements use the class attribute.

<div class="img">
     <img class="image" src="aithousa_anamonis_1.jpg" alt="Αίθουσα αναμονής 1" width="300" height="200">
</div>
<div class="img">
    <img class="image" src="aithousa_anamonis_2.jpg" alt="Αίθουσα αναμονής 2" width="300" height="200">
</div>
<div class="img">
     <img class="image" src="aithousa_anamonis_3.jpg" alt="Αίθουσα αναμονής 3" width="300" height="200">
</div>

Now you loop through all the elements with the given class name and add the event listeners.

var images = document.getElementsByClassName("image");
for(var i = 0; i < images.length; i++) {
  images[i].onclick = showCaption;
}


function showCaption(){
    modal.style.display = "block";
    modalImg.src = this.src;
    captionText.innerHTML = this.alt;
}
  • Like 1
Link to comment
Share on other sites

  • 2 months later...
<style>
div.img {margin:5px;border:1px solid #ccc;float:left;width:220px;}
div.img:hover {border:1px solid #777;}
div.img img {width:100%;height:auto;}
div.desc {padding:15px;text-align:center;}
.img {cursor:pointer;transition:0.3s;}
.image:hover {opacity:0.7;}
/* The Modal (background) */
.modal {
display:none; /* Hidden by default */
position:fixed; /* Stay in place */
z-index:1; /* Sit on top */
padding-top:100px; /* Location of the box */
left:0;
top:0;
width:100%; /* Full width */
height:100%; /* Full height */
overflow:auto; /* Enable scroll if needed */
background-color:rgb(0,0,0); /* Fallback color */
background-color:rgba(0,0,0,0.9); /* Black w/ opacity */
}
/* Modal Content (image) */
.modal-content {margin:auto;display:block;max-width:100%;}
/* Add Animation */
.modal-content, #caption {-webkit-animation-name:zoom;-webkit-animation-duration:0.6s;animation-name:zoom;animation-duration:0.6s;}
@-webkit-keyframes zoom {
from {-webkit-transform:scale(0)}
to {-webkit-transform:scale(1)}
}
@keyframes zoom {
from {transform:scale(0)}
to {transform:scale(1)}
}
/* The Close Button */
.close{position:absolute;top:15px;right:35px;color:#f1f1f1;font-size:40px;font-weight:bold;transition:0.3s;}
.close:hover,.close:focus{color:#bbb;text-decoration:none;cursor:pointer;}
/* 100% Image Width on Smaller Screens */
@media only screen and (max-width:700px){.modal-content {width:100%;}}
@media screen and (max-width:900px) {#content {margin-bottom:120px}}
</style>
<div id="content" class="col-9">
<h1>Φωτογραφίες</h1>
<div class="img"><img class="image" src="http://s.mikroviologos.gr/image/aithousa_anamonis_1.jpg" alt="Αίθουσα αναμονής 1"></div>
<div class="img"><img class="image" src="http://s.mikroviologos.gr/image/aithousa_anamonis_2.jpg" alt="Αίθουσα αναμονής 2"></div>
<div class="img"><img class="image" src="http://s.mikroviologos.gr/image/aithousa_anamonis_3.jpg" alt="Αίθουσα αναμονής 3"></div>
<div class="img"><img class="image" src="http://s.mikroviologos.gr/image/fygokentroi.jpg" alt="Φυγόκεντροι"></div>
<div class="img"><img class="image" src="http://s.mikroviologos.gr/image/analytes_1.jpg" alt="Αναλυτές 1"></div>
<div class="img"><img class="image" src="http://s.mikroviologos.gr/image/analytes_2.jpg" alt="Αναλυτές 2"></div>
<div class="img"><img class="image" src="http://s.mikroviologos.gr/image/analytes_3.jpg" alt="Αναλυτές 3"></div>
<!-- The Modal -->
<div id="myModal" class="modal">
<span class="close">×</span>
<img src="http://s.mikroviologos.gr/image/pixel.gif" class="modal-content" id="img01" alt="">
</div>
<script>
// Get the modal
var modal = document.getElementById('myModal');
// Get the image and insert it inside the modal
var images = document.getElementsByClassName("image");
for(var i = 0; i < images.length; i++) {images[i].onclick = showCaption;}
var modalImg = document.getElementById("img01");
function showCaption(){
modal.style.display = "block";
modalImg.src = this.src;
}
// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];
// When the user clicks on <span> (x), close the modal
span.onclick = function() {modal.style.display = "none";}
modal.onclick = function() {modal.style.display = "none";}
</script>

I think I put all the relative code. It works great, you can see here.

Link to comment
Share on other sites

  • 2 months later...

I tried implementing the above into my code, but it doesn't work, is there anybody who can see where I messed up?

 

html:

 

<!-- Portfolio -->
<section id="portfolio" class="two">
<div class="container">


<header>
<h2>Portfolio</h2>
</header>


<p>Hieronder vind je een groepering van mijn favoriete werk. Wil je al mijn werk zien en in de toekomst niets meer missen volg me dan op social media. Je vindt de verschillende links terug onderaan het navigatiepaneel.</p>


<div class="row">
<div class="4u 12u$(mobile)">
<article class="item">
<a class="image fit"><img class="image" src="images/IMG_4277.jpg" alt="Endless Earth" /></a>
<header>
 <h3>Endless Earth</h3>
</header>
</article>
                                    <article class="item">
<a class="image fit"><img class="image" src="images/IMG_5389.jpg" alt="De Melle" /></a>
<header>
 <h3>De Melle</h3>
 </header>
 </article>
<article class="item">
<a class="image fit"><img class="image" src="images/IMG_0550.jpg" alt="Capreolus capreolus" /></a>
<header>
<h3>Capreolus capreolus</h3>
</header>
</article>
                                    <article class="item">
<a class="image fit"><img class="image" src="images/IMG_4316.jpg" alt="The Calm" /></a>
<header>
<h3>The Calm</h3>
</header> 
                                    </article>
</div>
<div class="4u 12u$(mobile)">
<article class="item">
<a class="image fit"><img class="image" src="images/IMG_3143_V2.jpg" alt="De Flaes" /></a>
<header>
<h3>De Flaes</h3>
</header>
</article>
                                    <article class="item">
<a class="image fit"><img class="image" src="images/IMG_4050.jpg" alt="Vroege Grazer" /></a>
<header>
<h3>Vroege Grazer</h3>
 </header>
 </article>
<article class="item">
   <a class="image fit"><img class="image" src="images/IMG_4035.jpg" alt="Early Mornings" /></a>
<header>
<h3>Early Mornings</h3>
 </header>
</article>
                                    <article class="item">
<a class="image fit"><img class="image" src="images/IMG_4758.jpg" alt="King Fisher Back Pose" /></a>
<header>
<h3>King Fisher Back Pose</h3>
 </header>
 </article>
</div>
<div class="4u$ 12u$(mobile)">
<article class="item">
<a class="image fit"><img class="image" src="images/IMG_7110.jpg" alt="Verboden Toegang" /></a>
<header>
<h3>Verboden Toegang</h3>
 </header>
 </article>
                                    <article class="item">
<a class="image fit"><img class="image" src="images/IMG_6985.jpg" alt="Het Schildershoekje" /></a>
<header>
<h3>Het Schildershoekje</h3>
 </header>
 </article>
<article class="item">
<a class="image fit"><img class="image" src="images/IMG_4310.jpg" alt="Trees in the clouds" /></a>
<header>
<h3>Trees in the clouds</h3>
</header>
</article>
                                    <article class="item">
<a class="image fit"><img class="image" src="images/IMG_7487.jpg" alt="De Hoge Venen" /></a>
<header>
<h3>De Hoge Venen</h3>
 </header>
 </article>
</div>
</div>


</div>
                     
  <!-- The Modal -->
<div id="myModal" class="modal">


  <!-- The Close Button -->
<span class="close" onclick="document.getElementById('myModal').style.display='none'">×</span>


  <!-- Modal Content (The Image) -->
<img class="modal-content" id="img01" alt="">


  <!-- Modal Caption (Image Text) -->
<div id="caption"></div>
</div>


                    </section>
javascript:

// Get the modal
var modal = document.getElementById('myModal');


// Get the image and insert it inside the modal - use its "alt" text as a caption
var img = document.getElementsByClassName("demo");
for(var i = 0;  i < images.length; i++) {images[i].onclick = showCaption;}
var modalImg = document.getElementById("img01");
function showCaption(){
    modal.style.display = "block";
    modalImg.src = this.src;}


// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];


// When the user clicks on <span> (x), close the modal
span.onclick = function() {modal.style.display = "none";}
modal.onclick = function() {modal.style.display = "none";}
Edited by Yumiyahachiman
Link to comment
Share on other sites

1) You are telling it to look for images with class name 'demo'? there are no such images, they have class name 'image',

 

2) You have assigned the variable 'img' to class list of img elements with 'demo' class name (which don't exist), but! The for loop requires variable 'images' to identify how many img elements to loop through, and add click event to run function 'showCaption' when clicked.

Link to comment
Share on other sites

1) Thank you, I forgot to change that one demo.

 

2) isn't this part supposed to run the showcaption:

for(var i = 0;  i < images.length; i++) {images[i].onclick = showCaption;}

Only changing the "demo" to "image" for the img variable doesn't solve it

 

I'm a beginner, so sorry if I'm a bit slow to understand.

Link to comment
Share on other sites

Yes that runs show caption, BUT! in red

 

var img = document.getElementsByClassName("image");
for(var i = 0; i < images.length; i++) {images[i].onclick = showCaption;}

 

Refers to a variable that is of elements that will have classname 'image', YOUR variable is 'img' (in lime) so 'images' variable is undefined, and therefore not recognised, so it can't add the click events to caption function.

Link to comment
Share on other sites

ok, so I think I followed all instructions so far.

It opens the modal for every image I click on, but it doesnt show an image, it shows the broken image icon.

// Get the modal
var modal = document.getElementById('myModal');

// Get the image and insert it inside the modal - use its "alt" text as a caption
var images = document.getElementsByClassName("image");
for(var i = 0;  i < images.length; i++) {images[i].onclick = showCaption;}
var modalImg = document.getElementById("img01");
function showCaption(){
    modal.style.display = "block";
    modalImg.src = this.src;}

// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];

// When the user clicks on <span> (x), close the modal
span.onclick = function() {modal.style.display = "none";}
modal.onclick = function() {modal.style.display = "none";}
Link to comment
Share on other sites

So the last few days I've been trying to figure it out with what you've told me but...
Here's my thinking process:
// Get the modal - creating the variable "modal"
var modal = document.getElementById('myModal');

this refers to:

  <!-- The Modal -->
<div id="myModal" class="modal">

Create var images = a document with my 12 pictures (with class "image"):

// Get the image and insert it inside the modal - use its "alt" text as a caption
var images = document.getElementsByClassName("image");

Clicking on one of the images starts the function showCaption:

for(var i = 0;  i < images.length; i++) {images[i].onclick = showCaption;}

The function calls the modal and (here I'm not sure) says the modal image is the src from modalImg

function showCaption(){
    modal.style.display = "block";
    modalImg.src = this.src;}

The var modalImg is a doc filled with img01

var modalImg = document.getElementById("img01");

Here we have img01 defined (and I think this is where I screw up).

I've tried adding src="", I've tried adding src="images/pic07.jpg" (so with image linked), I've tried adding class"image", nothing works.
I believe I have te refer to the images here somehow, just can't figure out how ... Hariskars example above seems to refer to a random src...
 <!-- Modal Content (The Image) -->
<img src="" alt="" class="modal-content" id="img01">

And the rest is for closing and adding the caption...

// Get the <span> element that closes the modal
var span = document.getElementsByClassName("close")[0];

// When the user clicks on <span> (x), close the modal
span.onclick = function() {modal.style.display = "none";}
modal.onclick = function() {modal.style.display = "none";}

  <!-- The Close Button -->
<span class="close" onclick="document.getElementById('myModal').style.display='none'">×</span>

  <!-- Modal Caption (Image Text) -->
<div id="caption"></div>
</div>
Link to comment
Share on other sites

The var modalImg refers to img within modal modalImg.src refers to attribute 'src' of the modal img, this.src refers the gallery img that was clicked and its 'src' attribute value ie image path, so the modal image path will now equal the image path of image clicked.

 

Your problem is that class 'image' is only supposed to appear on the gallery images, so the loop that applys onclick event and call of function is only applied to these images, but you have applied the class of 'image' to the anchor surrounding the images, so these are included in the loop, BUT! The anchor element does not have a 'src' attribute its a link NOT A IMAGE, the loop does not know the difference, it just loops through elements with class 'image'. Instead of looping through just 10 items which are just supposed to be images, it loops through 20 because the anchors are included in the length (total) of elements with class 'image'.

 

Now! Because anchors don't have attribute 'src' the src of modal image will have src attribute value of 'undefined', and so no image will show.

Link to comment
Share on other sites

Sensei,

 

Some additional research points out

1* "The most important attribute of the <a> element is the href attribute, which indicates the link's destination."

So like you say I cannot use the anchor.

2* img only has one attribute: src

3* "The <div> tag is used to group block-elements to format them with CSS." But in haiskar's example it works so...

 

so in short replace the a's by div's as in the example by hariskar:

 

from:


<article class="item">
<a class="image fit"><img class="image" src="images/IMG_4277.jpg" alt="Endless Earth"></a>
<header>
 <h3>Endless Earth</h3>
</header>
</article>

to:

<article class="item">
<div class="image fit"><img class="image" src="images/IMG_4277.jpg" alt="Endless Earth"></div>
<header>
 <h3>Endless Earth</h3>
</header>
</article>

I'm guessing that is not what you mean, cause it doesn't change anything...

 

any more tips for this baboon unworthy of your teachings?

 

Edited by Yumiyahachiman
Link to comment
Share on other sites

AAAAAAAAAAAAAAAAAAARRRRRRRRRRRRRGGGGGGGGGGGGGHHHHHHHHHHHHHHHHHHHHH!!!!!!!!!!!!!!!!!!!!!!!!

 

IF YOU FOLLOWED hariskar example, and used exact BUT! DIFFERENT classes on div and img that YOU HAVE USED!, you would NOT BE HAVING THIS ISSUE.

 

ANY ELEMENT WHATEVER IT IS, THAT USES THE CLASS 'image' WILL BE TREATED AS A IMAGE (img tag) AND LOOPED THROUGH. YOU WANT TO ONLY TARGET IMG ELEMENT BECAUSE THAT IS THE ELEMENT THAT HAS SOURCE ATTRIBUTE 'src' THAT YOU WANT TO COPY TO THE MODAL IMAGE

 

<a class="image fit"><img class="image" src="images/IMG_4277.jpg" alt="Endless Earth"></a> = 'a' and 'img' element will be looped through, but! the 'a' tag does not use 'src' attribute, outcome modal src attribute will be 'undefined' and fail

 

<div class="image fit"><img class="image" src="images/IMG_4277.jpg" alt="Endless Earth"></div>= 'div' and 'img' element will be looped through, but! the 'div' tag does not use 'src' attribute, outcome modal src attribute will be 'undefined' and fail

 

COMPARED TO hariskar example

<div class="img"><img class="image" src="http://s.mikroviologos.gr/image/aithousa_anamonis_1.jpg" alt="Αίθουσα αναμονής 1"></div> = only img tag will be looped through, it has class 'image', no other other elements other-than other img element in the gallery will have this class, karma is balanced, the outcome will the modal image will receive the clicked img tags image path 'images/IMG_4277.jpg' all will be good!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...