I can't get this effect to work on multiple images. JavaScript is calling for the getElementById it seems to only work for a single image,
I've tried to change it to getElementByClassName (and also the HTML and CSS) but then the function stops working, how can I get this effect on multiple images/ divs?
window.onload = function() {
var modal = document.getElementById('myModal');
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;
};
var span = document.getElementsByClassName("modal")[0];
span.onclick = function() {
modal.style.display = "none";
};
};
.modal {
display: none;
position: fixed;
z-index: 1;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.9);
}
.modal-content {
margin: auto;
display: block;
width: 80%;
max-width: 700px;
}
#caption {
margin: auto;
display: block;
width: 80%;
max-width: 700px;
text-align: center;
color: #ccc;
padding: 10px 0;
height: 150px;
}
#myImg:hover {
cursor: pointer;
}
#-webkit-keyframes zoom {
from {
-webkit-transform: scale(0)
}
to {
-webkit-transform: scale(1)
}
}
#keyframes zoom {
from {
transform: scale(0.1)
}
to {
transform: scale(1)
}
}
.close {
position: absolute;
top: 15px;
right: 35px;
color: white;
font-size: 60px;
font-weight: bold;
;
}
.close:hover {
color: #FFD270;
text-decoration: none;
cursor: pointer;
}
#myImg {
opacity: 1;
display: inline-block;
width: 100%;
height: auto;
transition: .45s ease;
backface-visibility: hidden;
margin: 20px;
}
<div class="myndir-a4" data-title="">
<img id="myImg" src="..\01.jpg" alt="this works fine">
<div id="myModal" class="modal">
<span class="close">X</span>
<img id="img01" class="modal-content" src="..\01.jpg" alt="">
<div id="caption"></div>
</div>
</div>
<div class="myndir-a4" data-title="">
<img id="myImg" src="..\02.jpg" alt="nothing happens">
<div id="myModal" class="modal">
<span class="close">X</span>
<img id="img01" class="modal-content" src="..\02.jpg" alt="">
<div id="caption"></div>
</div>
</div>
The answer is delegation
Note
changed display: none to hidden on the tag and
changed most IDs to class or removed them since they are no longer needed due to relative addressing
It would even be possible to have just one modal
window.addEventListener("DOMContentLoaded", () => {
document.getElementById("container").addEventListener("click", e => {
const tgt = e.target;
if (!tgt.matches(".myImg") && !tgt.matches(".close")) return; // not the image or close
const parent = tgt.closest("div.myndir-a4");
const modal = parent.querySelector('.modal');
if (tgt.matches(".close")) {
modal.hidden = true;
return;
}
const modalImg = parent.querySelector("img.modal-content");
const captionText = parent.querySelector(".caption");
modal.hidden = false;
modalImg.src = tgt.src;
captionText.innerHTML = tgt.alt;
});
});
.modal {
position: fixed;
z-index: 1;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.9);
}
.modal-content {
margin: auto;
display: block;
width: 80%;
max-width: 700px;
}
.caption {
margin: auto;
display: block;
width: 80%;
max-width: 700px;
text-align: center;
color: #ccc;
padding: 10px 0;
height: 150px;
}
.myImg:hover {
cursor: pointer;
}
#-webkit-keyframes zoom {
from {
-webkit-transform: scale(0)
}
to {
-webkit-transform: scale(1)
}
}
#keyframes zoom {
from {
transform: scale(0.1)
}
to {
transform: scale(1)
}
}
.close {
position: absolute;
top: 15px;
right: 35px;
color: white;
font-size: 60px;
font-weight: bold;
;
}
.close:hover {
color: #FFD270;
text-decoration: none;
cursor: pointer;
}
.myImg {
opacity: 1;
display: inline-block;
width: 100%;
height: auto;
transition: .45s ease;
backface-visibility: hidden;
margin: 20px;
}
<div id="container">
<div class="myndir-a4" data-title="">
<img class="myImg" src="https://via.placeholder.com/728x90.png?text=image1" alt="this works fine">
<div class="modal" hidden>
<span class="close">X</span>
<img class="modal-content" src="" alt="">
<div class="caption"></div>
</div>
</div>
<div class="myndir-a4" data-title="">
<img class="myImg" src="https://via.placeholder.com/728x90.png?text=image2" alt="This ALSO works now">
<div class="modal" hidden>
<span class="close">X</span>
<img class="modal-content" src="" alt="">
<div class="caption"></div>
</div>
</div>
</div>
I get
Related
Im not really sure why the span tag is not closing
Does it have to do with my selection being a div in js?
Please let me know what I can change in order to make this work.
Ive tried to switch out the labels of the classes and tested selectors as well
Here is my code.
document.querySelectorAll('.imageContainer div').forEach(image => {
image.onclick = () => {
document.querySelector('.popup-image').style.display = 'block';
document.querySelector('.popup-image img').div = image.getAttribute('data-img');
}
});
document.querySelector('.popup-image span').onclick = () => {
document.querySelector('.popup-image').style.display = 'none';
};
/* modal */
.container .popup-image {
position: fixed;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.641);
height: 100%;
width: 100%;
z-index: 100;
display: none;
}
.container .popup-image span {
position: absolute;
top: 0;
right: 10px;
font-size: bolder;
color: #fff;
cursor: pointer;
z-index: 100;
}
.container .popup-image img {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 5px solid #fff;
width: 750px;
object-fit: cover;
}
#media only screen and (max-width: 600px) {
.container .popup-image img {
width: 99%;
}
}
<div class="imageContainer">
<div class="entry work-entry branding">
<div class="entry-image image imageBG" data-img="./src/assets/img/feature1.jpeg">
</div>
<div class="work-entry-hover">
<div class="work-entry-content">
<div class="work-entry-title">Brand</div>
<div class="work-entry-cat">Los Angeles, CA</div>
</div>
</div>
</div>
<!-- modal -->
<div class="popup-image">
<img src="./src/assets/img/feature1.jpeg" alt="">
<span>×</span>
</div>
</div>
Since the 'x' button is inside the other element, the function to set display: block is being called when you click on the span, which is overriding the display: none; that you're setting. You can stop this by running e.stopPropagation(); in the event handler, which will prevent the click event from triggering on any parent elements.
document.querySelectorAll('.imageContainer div').forEach(image => {
image.onclick = () => {
document.querySelector('.popup-image').style.display = 'block';
document.querySelector('.popup-image img').div = image.getAttribute('data-img');
}
});
document.querySelector('.popup-image span').onclick = (e) => {
e.stopPropagation();
document.querySelector('.popup-image').style.display = 'none';
};
/* modal */
.container .popup-image {
position: fixed;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.641);
height: 100%;
width: 100%;
z-index: 100;
display: none;
}
.container .popup-image span {
position: absolute;
top: 0;
right: 10px;
font-size: bolder;
color: #fff;
cursor: pointer;
z-index: 100;
}
.container .popup-image img {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 5px solid #fff;
width: 750px;
object-fit: cover;
}
#media only screen and (max-width: 600px) {
.container .popup-image img {
width: 99%;
}
}
<div class="imageContainer">
<div class="entry work-entry branding">
<div class="entry-image image imageBG" data-img="./src/assets/img/feature1.jpeg">
</div>
<div class="work-entry-hover">
<div class="work-entry-content">
<div class="work-entry-title">Brand</div>
<div class="work-entry-cat">Los Angeles, CA</div>
</div>
</div>
</div>
<!-- modal -->
<div class="popup-image">
<img src="./src/assets/img/feature1.jpeg" alt="">
<span>×</span>
</div>
</div>
I created a gallery using the following codepen and now I'm trying to add the function click to expand an image, using this JS method. Sadly I cannot get it to work.
Any advice would be very helpful, either regarding this expand option or an alternative. Mind you I'm completely new to JS.
Thanks in advance!
var modal = document.getElementById('myModal');
var img = document.getElementById('myImg');
var modalImg = document.getElementById("image");
img.onclick = function(){
modal.style.display = "block";
modalImg.src = this.src;
captionText.innerHTML = this.alt;
}
var span = document.getElementsByClassName("close")[0];
span.onclick = function() {
modal.style.display = "none";
}
/*main div*/
.ponudba {
background-color: rgb(0, 0, 0);
z-index: 3;
}
.image-grid {
padding: 12px;
}
.image-row {
display: flex;
}
.image-row .image {
margin: 12px;
height: 220px;
}
.image {
background-repeat: no-repeat;
background-size: cover;
background-position: center center;
border-radius: 3px;
transition-duration: 0.5s;
filter: contrast(75%);
transition: all 0.3s ease-in;
box-shadow: 0 3px 4px rgba(0, 0, 0, 0.3),
0 3px 4px rgba(0, 0, 0, 0.15),
0 3px 4px rgba(0, 0, 0, 0.7);
margin: 0 0 0 15%;
display: block;
height: 100vh;
max-width: 100%;
animation-name: zoom;
animation-duration: 0.6s;
z-index: 3;
}
.image:hover {
filter: contrast(100%);
transition: all 0.3s ease-out;
cursor: pointer;
}
.image-01 {
background-image: url(images/...jpg);
flex: 2;
background-position: 50% 60%;
}
.image-02 {
background-image: url(images/...jpg);
flex: 1.2;
}
.image-03 {
background-image: url(images/...jpg);
flex: 1.5;
background-position: 50% 70%;
}
.image-04 {
background-image: url(images/...jpg);
flex: 3;
background-position: 50% 60%;
}
.image-05 {
background-image: url(images/...jpg);
flex: 3;
}
.image-06 {
background-image: url(images/...jpg);
flex: 2;
}
.image-07 {
background-image: url(images/...jpg);
flex: 1.5;
}
.image-08 {
background-image: url(images/...jpg);
flex: 2.5;
background-position: 50% 70%;
}
.image-09 {
background-image: url(images/...jpg);
flex: 1;
}
.image-10 {
background-image: url(images/...jpg);
flex: 3;
background-position: 50% 80%;
}
#myImg {
border-radius: 3px;
cursor: pointer;
transition: 0.3s;
}
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.9);
}
#keyframes zoom {
from {transform: scale(0.1)}
to {transform: scale(1)}
}
.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;
}
#media only screen and (max-width: 700px){
.modal-content {
width: 100%;
}
.image-row {
flex-direction: column;
}
.image-row .image {
flex-basis: auto;
}
}
<div class="ponudba" id="ponudba">
<div class="image-grid">
<div class="image-row">
<div class="image image-01" id="image-01"></div>
<div class="image image-02" id="image-02"></div>
<div class="image image-03" id="image-03"></div>
<div class="image image-04" id="image-04"></div>
</div>
<div class="image-row">
<div class="image image-06" id="image-06"></div>
<div class="image image-05" id="image-05"></div>
<div class="image image-07" id="image-07"></div>
</div>
<div class="image-row">
<div class="image image-08" id="image-08"></div>
<div class="image image-09" id="image-09"></div>
<div class="image image-10" id="image-10"></div>
</div>
</div>
<div id="myModal" class="modal">
<span class="close">×</span>
<img class="modal-content" id="image">
</div>
</div>
id should be unique.
If you have multiple images, you can use getElementsByClassName to get all elements you need to expand.
Then use for loop to add onClick function to each element.
let imgs = document.getElementsByClassName("image"),
imgModal = document.getElementById('image'),
modal = document.getElementById('myModal');
for (let i = 0; i < imgs.length; i++) {
imgs[i].onclick = function (e) { imgZoom(e) }
}
function imgZoom(e) {
modal.style.display = 'block';
let src = e.target.style.backgroundImage.slice(4, -1).replace(/['"]/g, "")
imgModal.src = src
}
let span = document.getElementsByClassName('close')[0];
span.onclick = function () {
modal.style.display = 'none';
}
Because your image is background-img in css, use backgroundImage.slice(4, -1).replace(/['"]/g, "") to get url.
/-----Edit-----/
Sorry I made some mistakes in my code.
let imgs = document.getElementsByClassName("image-row") should be
let imgs = document.getElementsByClassName("image")
for (let i = 0; i < imgBlocks.length; i++) should be
for (let i = 0; i < imgs.length; i++)
modal is not defined
background-img: url('...'); should write in html file, or js can't get the url.
<div class="image image-01" id="image-01" style="background-image: url('22.png');"></div>
About your question
It's not necessary to add an id on every image (except modal) in this case.
I select images by class name image in:
<div class="image image-01" id="image-01"></div>
Do I need to add a for loop for every element?
You need to add onclick to every element you want to expand.
Due to I selected images by class name, the object will be something like this
Use for loop to add onclick for every <div class="image imag...</div>
style.backgroundImage = url('22.png')
.slice(4, -1).replace(/['"]/g, "") will create a string from url("22.png"), select "22.png", then replace ' or " if exist.
The final result will be 22.png.
So after asking a collegue for help, this is what I got - an image gallery with clickable images.
Here's the pen: https://codepen.io/fullstackgenerator/pen/YzaqYdb
var modal = document.getElementById('Modal');
var imgaes = document.getElementsByClassName('image');
var modalImg = document.getElementById("image-modal");
imgaes = [].slice.call(imgaes);
console.log(imgaes);
imgaes.forEach(function(item){
item.onclick = function(){
modal.style.display = "block";
modalImg.src = this.getAttribute('src');
}
})
var span = document.getElementsByClassName("close")[0];
modalImg.onclick = function() {
modal.style.display = "none";
}
body {
margin: 0;
background-color: rgb(0, 0, 0);
}
.ponudba {
position: relative;
background-color: rgb(0, 0, 0);
height: 100vh;
max-width: 100%;
background-repeat: no-repeat;
background-size: cover;
background-position: 50% 50%;
z-index: 6;
}
.image-grid {
padding: 12px;
}
.image-row {
display: flex;
}
.image-row .image {
margin: 12px;
height: 220px;
}
.image {
background-repeat: no-repeat;
background-size: cover;
background-position: center center;
border-radius: 3px;
height: 95%;
max-width: 100%;
}
.image:hover {
transition: all 0.3s ease-out;
cursor: pointer;
}
.image-01 {
background-image: url(https://res.cloudinary.com/dtpgi0zck/image/upload/s--fMAvJ-9u--/c_fit,h_580,w_860/v1/EducationHub/photos/sun-blasts-a-m66-flare.jpg);
flex: 2;
background-position: 50% 60%;
}
.image-02 {
background-image: url(https://cdn.mos.cms.futurecdn.net/KqzWwkCMPeZHFra2hkiJWj.jpg);
flex: 1.2;
}
.image-03 {
background-image: url(https://acs-h.assetsadobe.com/is/image//content/dam/cen/99/11/WEB/09911-feature3-venus.jpg/?$responsive$&wid=700&qlt=90,0&resMode=sharp2);
flex: 1.5;
background-position: 50% 70%;
}
.image-04 {
background-image: url(https://cdn.mos.cms.futurecdn.net/yCPyoZDQBBcXikqxkeW2jJ-1200-80.jpg);
flex: 3;
background-position: 50% 60%;
}
.image-05 {
background-image: url(https://images.24ur.com/media/images/1000xX/Oct2020/51ae60002d9189cc75b0_62469955.jpg?v=6e93);
flex: 3;
}
.image-06 {
background-image: url(https://upload.wikimedia.org/wikipedia/commons/thumb/5/50/Jupiter%2C_image_taken_by_NASA%27s_Hubble_Space_Telescope%2C_June_2019_-_Edited.jpg/801px-Jupiter%2C_image_taken_by_NASA%27s_Hubble_Space_Telescope%2C_June_2019_-_Edited.jpg);
flex: 2;
}
.image-07 {
background-image: url(https://images.24ur.com/media/images/884xX/Oct2019/d33eec2c51_62323281.jpg?v=d41d);
flex: 1.5;
}
.image-08 {
background-image: url(https://upload.wikimedia.org/wikipedia/commons/thumb/4/48/Uranus_as_seen_by_NASA%27s_Voyager_2_%28remastered%29.png/800px-Uranus_as_seen_by_NASA%27s_Voyager_2_%28remastered%29.png);
flex: 2.5;
}
.image-09 {
background-image: url(https://upload.wikimedia.org/wikipedia/commons/thumb/5/56/Neptune_Full.jpg/640px-Neptune_Full.jpg);
flex: 1;
}
.image-10 {
background-image: url(https://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/Pluto_in_True_Color_-_High-Res.jpg/800px-Pluto_in_True_Color_-_High-Res.jpg);
flex: 3;
}
#myImg {
border-radius: 3px;
cursor: pointer;
transition: 0.3s;
}
.modal {
display: none;
position: fixed;
z-index: 10;
left: 0;
top: 0;
width: 100%;
height: 100vh;
overflow: auto;
background-color: rgb(0,0,0);
background-color: rgba(0,0,0,0.9);
}
.modal-content {
margin: auto;
display: block;
animation-name: zoom;
animation-duration: 0.6s;
}
#keyframes zoom {
from {transform: scale(0.1)}
to {transform: scale(1)}
}
#media only screen and (max-width: 700px){
.modal-content {
width: 100%;
}
.image-row {
flex-direction: column;
}
.image-row .image {
flex-basis: auto;
}
}
<!--a BIG thank you to #awecodeman!-->
<div class="ponudba" id="ponudba">
<div class="image-grid">
<div class="image-row">
<div class="image image-01" id="image-01" src="https://res.cloudinary.com/dtpgi0zck/image/upload/s--fMAvJ-9u--/c_fit,h_580,w_860/v1/EducationHub/photos/sun-blasts-a-m66-flare.jpg"></div>
<div class="image image-02" id="image-02" src="https://cdn.mos.cms.futurecdn.net/KqzWwkCMPeZHFra2hkiJWj.jpg"></div>
<div class="image image-03" id="image-03" src="https://acs-h.assetsadobe.com/is/image//content/dam/cen/99/11/WEB/09911-feature3-venus.jpg/?$responsive$&wid=700&qlt=90,0&resMode=sharp2"></div>
<div class="image image-04" id="image-04" src="https://cdn.mos.cms.futurecdn.net/yCPyoZDQBBcXikqxkeW2jJ-1200-80.jpg"></div>
</div>
<div class="image-row">
<div class="image image-05" id="image-05" src="https://images.24ur.com/media/images/1000xX/Oct2020/51ae60002d9189cc75b0_62469955.jpg?v=6e93"></div>
<div class="image image-06" id="image-06" src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/50/Jupiter%2C_image_taken_by_NASA%27s_Hubble_Space_Telescope%2C_June_2019_-_Edited.jpg/801px-Jupiter%2C_image_taken_by_NASA%27s_Hubble_Space_Telescope%2C_June_2019_-_Edited.jpg"></div>
<div class="image image-07" id="image-07" src="https://images.24ur.com/media/images/884xX/Oct2019/d33eec2c51_62323281.jpg?v=d41d"></div>
</div>
<div class="image-row"">
<div class="image image-08" id="image-08" src="https://upload.wikimedia.org/wikipedia/commons/thumb/4/48/Uranus_as_seen_by_NASA%27s_Voyager_2_%28remastered%29.png/800px-Uranus_as_seen_by_NASA%27s_Voyager_2_%28remastered%29.png"></div>
<div class="image image-09" id="image-09" src="https://upload.wikimedia.org/wikipedia/commons/thumb/5/56/Neptune_Full.jpg/640px-Neptune_Full.jpg"></div>
<div class="image image-10" id="image-10" src="https://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/Pluto_in_True_Color_-_High-Res.jpg/800px-Pluto_in_True_Color_-_High-Res.jpg"></div>
<div id="Modal" class="modal">
<span class="close">×</span>
<img class="modal-content image" id="image-modal"></div>
</div>
</div>
I have a straightforward multi-image modal set up which works perfectly. However, the page I am trying to integrate it on is set up as follows: I have a header, a set of links to the left, and a main section next to the links. When a link is clicked it changes the content of the main section through a hide/show function. In this manner all of the site is on one page. The problem is that when I place the modal inside the hidden div of choice, the images show up when the main contents is changed, but the modal does not open when the image is clicked. Here is the code for the main div and the hidden div where the modal will be (the user needs to click on where the image would be that says "fall bill" to open the div where the modal is. You will see that I placed some images in as holders. The images fade when hovered as they are supposed to. I cannot figure out any reason why the modal will not show up in such an instance but works if it is not inside a div that can be hidden.
Here is a the code:
var modal = document.getElementById('myModal');
var images = document.getElementsByClassName('img');
var modalImg = document.getElementById("img01");
for (var i = 0; i < images.length; i++) {
var img = images[i];
img.onclick = function(evt) {
console.log(evt);
modal.style.display = "block";
modalImg.src = this.src;
}
}
var span = document.getElementsByClassName("close")[0];
span.onclick = function() {
modal.style.display = "none";
}
function show(param_div_id) {
document.getElementById('main').innerHTML = document.getElementById(param_div_id).innerHTML;
}
.img {
border-radius: 5px;
cursor: pointer;
transition: 0.3s;
}
.img:hover {
opacity: 0.8;
}
.modal {
display: none;
/* Hidden by default */
position: fixed;
/* Stay in place */
z-index: 10;
/* 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 {
margin: auto;
display: block;
width: 80%;
max-width: 700px;
}
.modal-content,
#caption {
animation-name: zoom;
animation-duration: 0.6s;
}
#keyframes zoom {
from {
transform: scale(0)
}
to {
transform: scale(1)
}
}
.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;
}
#media only screen and (max-width: 700px) {
.modal-content {
width: 100%;
}
}
#main {
background-image: url('bkgd.jpg');
display: block;
width: 690px;
font-family: "Book Antiqua";
color: #004B97;
font-size: 16pt;
padding: 2%;
margin: 5px;
border-radius: 15px;
border: medium #9999FF solid;
}
.mainContents {
display: flex;
flex-wrap: wrap;
margin: 0 auto;
position: relative;
width: 690px;
flex-wrap: wrap;
justify-content: center;
}
#home,
#bills,
#munTax,
#schoolTax,
#interimTax,
#taxCert,
#dupsReceipts,
#directions,
#FAQ {
display: none;
width: 300px;
font-family: "Book Antiqua";
color: #004B97;
}
.head {
width: 100%;
text-align: center;
font-family: inherit;
font-size: 16pt;
color: #004B97;
padding-bottom: 10px;
}
.head2 {
position: relative;
width: 100%;
text-align: center;
font-family: inherit;
font-size: 14pt;
color: #835BF9;
padding-bottom: 15px;
}
.lower {
width: 100%;
display: flex;
margin: 0 auto auto 10;
flex-wrap: wrap;
justify-content: space-around;
padding: 10px;
align-items: center;
}
.pay {
text-align: center;
background-image: url('background.jpg');
color: #0D095E;
font-size: 14pt;
border: medium #9999FF solid;
border-radius: 15px;
padding: 5px;
margin: 5px;
}
<div id="main">
<div class="mainContents">
<div class="head">Outside Receiving Hours:<br/> Please use secure drop box outside building
</div>
<div class="head2">
<strong>2022 Millage Rates</strong><br/> County - 3.2273; Township - .62; PVSD (School + Library) = 23.8117
</div>
<div class="lower">
<div class="pay">
Pay Tax Bill Online<br/>
<img alt="Pay Online" height="80" src="payonline.png" width="144">
</div>
<div class="pay">
Understanding Your Tax Bill<br/>
<button onclick="show('bills')" class="link"><img alt="Fall Bill" height="129" src="FallTaxBill-psd.png" width="300"></button>
</div>
</div>
</div>
</div>
<div id="bills">
<div class="mainContents">
<div class="head">Understanding Your Tax Bill</div><br/>
<div class="lower">
<div class="pay">
Spring Tax Bill<br/>
<img class="img" src="http://onebigphoto.com/uploads/2012/10/midnight-sun-in-lofoten-norway.jpg" alt="Midnight sun in Lofoten, Norway" width="300" height="200">
</div>
<div class="pay">
Fall Tax Bill<br/>
<img class="img" src="http://cdn-image.travelandleisure.com/sites/default/files/styles/1600x1000/public/1490029386/fisherman-cabin-hamnoy-lofoten-islands-norway-NORWAY0320.jpg?itok=cpPuUjh1" alt="Fishermen's cabins in Lofoten, Norway" width="300" height="200">
</div>
<div class="pay">
Fall Tax Bill Stubs<br/>
<img class="img" src="http://fjordtours.blob.core.windows.net/fjordtours-umbraco/1199/gerirangerfjord-per-ottar-walderhaug-fjordnorway.jpg" alt="Gerirangerfjord, Norway" width="300" height="200">
</div>
</div>
</div>
</div>
<div id="myModal" class="modal">
<span class="close">×</span>
<img class="modal-content" id="img01">
<div id="caption"></div>
</div>
the listeners are removed when content is swapped, add image listeners there instead:
var modal = document.getElementById('myModal');
var images = document.getElementsByClassName('img');
var modalImg = document.getElementById("img01");
var span = document.getElementsByClassName("close")[0];
span.onclick = function() {
modal.style.display = "none";
}
function show(param_div_id) {
document.getElementById('main').innerHTML = document.getElementById(param_div_id).innerHTML;
for (var i = 0; i < images.length; i++) {
var img = images[i];
img.onclick = function(evt) {
console.log(evt);
modal.style.display = "block";
modalImg.src = this.src;
}
}
}
.img {
border-radius: 5px;
cursor: pointer;
transition: 0.3s;
}
.img:hover {
opacity: 0.8;
}
.modal {
display: none;
/* Hidden by default */
position: fixed;
/* Stay in place */
z-index: 10;
/* 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 {
margin: auto;
display: block;
width: 80%;
max-width: 700px;
}
.modal-content,
#caption {
animation-name: zoom;
animation-duration: 0.6s;
}
#keyframes zoom {
from {
transform: scale(0)
}
to {
transform: scale(1)
}
}
.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;
}
#media only screen and (max-width: 700px) {
.modal-content {
width: 100%;
}
}
#main {
background-image: url('bkgd.jpg');
display: block;
width: 690px;
font-family: "Book Antiqua";
color: #004B97;
font-size: 16pt;
padding: 2%;
margin: 5px;
border-radius: 15px;
border: medium #9999FF solid;
}
.mainContents {
display: flex;
flex-wrap: wrap;
margin: 0 auto;
position: relative;
width: 690px;
flex-wrap: wrap;
justify-content: center;
}
#home,
#bills,
#munTax,
#schoolTax,
#interimTax,
#taxCert,
#dupsReceipts,
#directions,
#FAQ {
display: none;
width: 300px;
font-family: "Book Antiqua";
color: #004B97;
}
.head {
width: 100%;
text-align: center;
font-family: inherit;
font-size: 16pt;
color: #004B97;
padding-bottom: 10px;
}
.head2 {
position: relative;
width: 100%;
text-align: center;
font-family: inherit;
font-size: 14pt;
color: #835BF9;
padding-bottom: 15px;
}
.lower {
width: 100%;
display: flex;
margin: 0 auto auto 10;
flex-wrap: wrap;
justify-content: space-around;
padding: 10px;
align-items: center;
}
.pay {
text-align: center;
background-image: url('background.jpg');
color: #0D095E;
font-size: 14pt;
border: medium #9999FF solid;
border-radius: 15px;
padding: 5px;
margin: 5px;
}
<div id="main">
<div class="mainContents">
<div class="head">Outside Receiving Hours:<br/> Please use secure drop box outside building
</div>
<div class="head2">
<strong>2022 Millage Rates</strong><br/> County - 3.2273; Township - .62; PVSD (School + Library) = 23.8117
</div>
<div class="lower">
<div class="pay">
Pay Tax Bill Online<br/>
<img alt="Pay Online" height="80" src="payonline.png" width="144">
</div>
<div class="pay">
Understanding Your Tax Bill<br/>
<button onclick="show('bills')" class="link"><img alt="Fall Bill" height="129" src="FallTaxBill-psd.png" width="300"></button>
</div>
</div>
</div>
</div>
<div id="bills">
<div class="mainContents">
<div class="head">Understanding Your Tax Bill</div><br/>
<div class="lower">
<div class="pay">
Spring Tax Bill<br/>
<img class="img" src="http://onebigphoto.com/uploads/2012/10/midnight-sun-in-lofoten-norway.jpg" alt="Midnight sun in Lofoten, Norway" width="300" height="200">
</div>
<div class="pay">
Fall Tax Bill<br/>
<img class="img" src="http://cdn-image.travelandleisure.com/sites/default/files/styles/1600x1000/public/1490029386/fisherman-cabin-hamnoy-lofoten-islands-norway-NORWAY0320.jpg?itok=cpPuUjh1" alt="Fishermen's cabins in Lofoten, Norway" width="300" height="200">
</div>
<div class="pay">
Fall Tax Bill Stubs<br/>
<img class="img" src="http://fjordtours.blob.core.windows.net/fjordtours-umbraco/1199/gerirangerfjord-per-ottar-walderhaug-fjordnorway.jpg" alt="Gerirangerfjord, Norway" width="300" height="200">
</div>
</div>
</div>
</div>
<div id="myModal" class="modal">
<span class="close">×</span>
<img class="modal-content" id="img01">
<div id="caption"></div>
</div>
I created a simple gallery with images resized on click and added "x" to image containers which remove the class (.bigger). However, I'm trying to figure out how to add another class (.invisible) that will remove "x" when the selected image has no class (.bigger). Can you help out a beginner coder?
How to make a condition: if an image DOES NOT have class .bigger, add class .invisible (to the cross)? I'm really grateful for any help.
const imgList = document.querySelectorAll("img");
const crosses = document.querySelectorAll(".imgContainer span");
for (let i = 0; i < imgList.length; i++) {
imgList[i].addEventListener("click", function() {
imgList.forEach((el) => el.classList.remove("bigger"));
imgList[i].classList.add("bigger");
});
}
for (let x = 0; x < crosses.length; x++) {
crosses[x].addEventListener("click", function() {
imgList.forEach((el) => el.classList.remove("bigger"));
crosses[x].classList.remove("invisible");
});
}
if (imgList[i].classList.contains("")) {
crosses[x].classList.add("invisible");
}
img {
width: 150px;
height: 120px;
object-fit: cover;
margin: 0 1rem;
opacity: 0.5;
transition: all 0.2s;
}
img:hover {
opacity: 1;
}
.imgContainer {
position: relative;
}
.imgContainer span {
position: absolute;
top: -5px;
right: 0;
cursor: pointer;
display: block;
width: 15px;
height: 15px;
background-color: transparent;
text-align: center;
line-height: 15px;
font-size: 30px;
}
.bigger {
width: 500px;
height: auto;
opacity: 1;
}
.invisible {
display: none;
}
<div class="imgContainer">
<span>×</span>
<img src="img1.jpg" alt="Tokyo1" />
</div>
<div class="imgContainer">
<span>×</span>
<img src="img2.jpg" alt="Tokyo2" />
</div>
<div class="imgContainer">
<span>×</span>
<img src="img3.jpg" alt="Tokyo3" />
</div>
If you iterate over the .imgContainer, you can more easily access the corresponding img and span.
Additionally, you can change the invisiblecss class to more specific .imgContainer span.invisible because .imgContainer span {display: block} would overwrite it.
const imgList = document.querySelectorAll(".imgContainer img");
const crossList = document.querySelectorAll(".imgContainer span");
document.querySelectorAll(".imgContainer").forEach((container) => {
const img = container.querySelector("img");
const cross = container.querySelector("span");
img.addEventListener("click", function () {
// Reset the classes of all images and spans.
imgList.forEach((el) => el.classList.remove("bigger"));
crossList.forEach((el) => el.classList.add("invisible"));
// make the image bigger and show the cross.
img.classList.add("bigger");
cross.classList.remove("invisible");
});
cross.addEventListener("click", function () {
img.classList.remove("bigger");
cross.classList.add("invisible");
});
});
img {
width: 150px;
height: 120px;
object-fit: cover;
margin: 0 1rem;
opacity: 0.5;
transition: all 0.2s;
}
img:hover {
opacity: 1;
}
.imgContainer {
position: relative;
}
.imgContainer span {
position: absolute;
top: -5px;
right: 0;
cursor: pointer;
display: block;
width: 15px;
height: 15px;
background-color: transparent;
text-align: center;
line-height: 15px;
font-size: 30px;
}
.imgContainer span.invisible {
display: none;
}
.bigger {
width: 500px;
height: auto;
opacity: 1;
}
<div class="imgContainer">
<span class="invisible">×</span>
<img src="https://via.placeholder.com/300" alt="Tokyo1" />
</div>
<div class="imgContainer">
<span class="invisible">×</span>
<img src="https://via.placeholder.com/300" alt="Tokyo2" />
</div>
<div class="imgContainer">
<span class="invisible">×</span>
<img src="https://via.placeholder.com/300" alt="Tokyo3" />
</div>
const imgList = document.querySelectorAll("img");
const crosses = document.querySelectorAll(".imgContainer span");
for (let i = 0; i < imgList.length; i++) {
imgList[i].addEventListener("click", function() {
imgList.forEach((el) => el.classList.remove("bigger"));
this.classList.add("bigger");
changeAction();
});
}
for (let x = 0; x < crosses.length; x++) {
crosses[x].addEventListener("click", function() {
imgList.forEach((el) => el.classList.remove("bigger"));
this.classList.remove("invisible");
});
}
function changeAction() {
for (let i = 0; i < imgList.length; i++) {
if (imgList[i].classList.contains("")) {
crosses[x].classList.add("invisible");
}
}
}
img {
width: 150px;
height: 120px;
object-fit: cover;
margin: 0 1rem;
opacity: 0.5;
transition: all 0.2s;
}
img:hover {
opacity: 1;
}
.imgContainer {
position: relative;
}
.imgContainer span {
position: absolute;
top: -5px;
right: 0;
cursor: pointer;
display: block;
width: 15px;
height: 15px;
background-color: transparent;
text-align: center;
line-height: 15px;
font-size: 30px;
}
.bigger {
width: 500px;
height: auto;
opacity: 1;
}
.invisible {
display: none;
}
<div class="imgContainer">
<span>×</span>
<img src="img1.jpg" alt="Tokyo1" />
</div>
<div class="imgContainer">
<span>×</span>
<img src="img2.jpg" alt="Tokyo2" />
</div>
<div class="imgContainer">
<span>×</span>
<img src="img3.jpg" alt="Tokyo3" />
</div>
In a gallery of images, it is possible to click on each image in order to enlarge it. The sources of the enlarged images are received from the background-image of the small ones. I want to create a previous and next button to these enlarged images.
I have done this previously for a set of images with separate divs. However, I have never done it with arrays. Here is my code.
var modal = document.getElementById("myModal");
var modalImg = document.getElementById("modalImg");
var imgArr = Array.from(document.querySelectorAll('.img-container .img'));
imgArr.forEach(function(img) {
img.onclick = function() {
var backgroundImage = img.style.backgroundImage.slice(4, -1).replace(/"/g, '');
modal.style.display = "flex";
modalImg.src = backgroundImage;
}
});
/* This is the part where I tried adding previous & next
functions, but it doesn't work and it makes the close
button not work either. */
/*
var prev = document.getElementsByClassName("prev");
var next = document.getElementsByClassName("next");
var index = 0;
imgArr[index] = modalImg.src;
next.addEventListener('click', nextImage);
function nextImage() {
for (i = 0; i < 10; i++) {
modalImg.src = imgArr[index + 1];
}
}
previous.addEventListener('click', previousImage);
function previousImage() {
for (i = 0; i < 10; i++) {
modalImg.src = imgArr[index - 1];
}
}
*/
// add caption
var captionText = document.getElementById("caption");
// close the modal
var span = document.getElementsByClassName("close")[0];
span.onclick = function() {
modal.style.display = "none";
}
.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;
}
.img {
display: block;
width: 200px;
height: 100%;
margin-right: 10px;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
cursor: pointer;
}
.img-container {
display: flex;
height: 100px;
min-height: 20rem;
}
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
box-sizing: border-box;
overflow: auto;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.9);
justify-content: center;
align-items: center;
}
.modal-content {
margin: auto;
display: block;
width: 80%;
max-width: 700px;
max-height: 80%;
object-fit: contain;
-o-object-fit: contain;
animation-name: zoom;
animation-duration: 0.6s;
}
/* Next & previous buttons */
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
-moz-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
width: auto;
padding: 0.8rem;
color: #777;
font-weight: normal;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
-webkit-user-select: none;
z-index: 3;
}
.prev:hover,
.next:hover {
color: #000;
}
.next {
right: 0;
}
.prev {
left: 0;
}
#keyframes zoom {
from {
transform: scale(0)
}
to {
transform: scale(1)
}
}
<div class="img-container">
<div id="tehran" class="img" style="background-image: url(https://images.unsplash.com/photo-1524567492592-cee28084482e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=600&q=60)">
</div>
<div id="masuleh" class="img" style="background-image: url(https://images.unsplash.com/photo-1567317255448-8e6c04e22114?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=634&q=80)">
</div>
<div id="zanjan" class="img" style="background-image: url(https://images.unsplash.com/photo-1518727577784-f62f1115eefb?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80)">
</div>
</div>
<!-- The Modal -->
<div id="myModal" class="modal">
<!-- Buttons -->
<span class="close">×</span>
<a class="prev">❮</a>
<a class="next">❯</a>
<!-- Modal Content -->
<img id="modalImg" class="modal-content">
<div id="caption"></div>
</div>
var modal = document.getElementById("myModal");
var modalImg = document.getElementById("modalImg");
var imgArr = Array.from(document.querySelectorAll('.img-container .img'));
var currentIndex = 0;
imgArr.forEach(function(img, i) {
img.onclick = function() {
currentIndex = i;
var backgroundImage = img.style.backgroundImage.slice(4, -1).replace(/"/g, '');
modal.style.display = "flex";
modalImg.src = backgroundImage;
}
});
var prev = document.getElementsByClassName("prev")[0];
var next = document.getElementsByClassName("next")[0];
next.addEventListener('click', nextImage);
function nextImage() {
currentIndex = (currentIndex+1)%imgArr.length;
var backgroundImage = imgArr[currentIndex].style.backgroundImage.slice(4, -1).replace(/"/g, '');
modalImg.src = backgroundImage
}
prev.addEventListener('click', previousImage);
function previousImage() {
currentIndex = (currentIndex+imgArr.length-1)%imgArr.length;
var backgroundImage = imgArr[currentIndex].style.backgroundImage.slice(4, -1).replace(/"/g, '');
modalImg.src = backgroundImage
}
// add caption
var captionText = document.getElementById("caption");
// close the modal
var span = document.getElementsByClassName("close")[0];
span.onclick = function() {
modal.style.display = "none";
}
.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;
}
.img {
display: block;
width: 200px;
height: 100%;
margin-right: 10px;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
cursor: pointer;
}
.img-container {
display: flex;
height: 100px;
min-height: 20rem;
}
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
box-sizing: border-box;
overflow: auto;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.9);
justify-content: center;
align-items: center;
}
.modal-content {
margin: auto;
display: block;
width: 80%;
max-width: 700px;
max-height: 80%;
object-fit: contain;
-o-object-fit: contain;
animation-name: zoom;
animation-duration: 0.6s;
}
/* Next & previous buttons */
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
-moz-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
width: auto;
padding: 0.8rem;
color: #777;
font-weight: normal;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
-webkit-user-select: none;
z-index: 3;
}
.prev:hover,
.next:hover {
color: #000;
}
.next {
right: 0;
}
.prev {
left: 0;
}
#keyframes zoom {
from {
transform: scale(0)
}
to {
transform: scale(1)
}
}
<div class="img-container">
<div id="tehran" class="img" style="background-image: url(https://images.unsplash.com/photo-1524567492592-cee28084482e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=600&q=60)">
</div>
<div id="masuleh" class="img" style="background-image: url(https://images.unsplash.com/photo-1567317255448-8e6c04e22114?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=634&q=80)">
</div>
<div id="zanjan" class="img" style="background-image: url(https://images.unsplash.com/photo-1518727577784-f62f1115eefb?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80)">
</div>
</div>
<!-- The Modal -->
<div id="myModal" class="modal">
<!-- Buttons -->
<span class="close">×</span>
<a class="prev">❮</a>
<a class="next">❯</a>
<!-- Modal Content -->
<img id="modalImg" class="modal-content">
<div id="caption"></div>
</div>
You can keep track of the currently clicked image, later you can increment/decrement the value based on which you can select image from the NodeList:
Please Note: You do not need Array.from() to implement forEach() on NodeList returned by querySelectorAll():
Try the following way:
var modal = document.getElementById("myModal");
var modalImg = document.getElementById("modalImg");
var imgArr = document.querySelectorAll('.img-container .img');
var curSrc;
imgArr.forEach(function(img, i) {
img.onclick = function() {
var backgroundImage = img.style.backgroundImage.slice(4, -1).replace(/"/g, '');
modal.style.display = "flex";
modalImg.src = backgroundImage;
curSrc = i;
}
});
var prev = document.querySelector(".prev");
var next = document.querySelector(".next");
next.addEventListener('click', nextImage);
function nextImage() {;
if(curSrc < imgArr.length - 1){
curSrc++;
modalImg.src = imgArr[curSrc].style.backgroundImage.slice(4, -1).replace(/"/g, '');
}
}
prev.addEventListener('click', previousImage);
function previousImage() {
if(curSrc>0){
curSrc--;
modalImg.src = imgArr[curSrc].style.backgroundImage.slice(4, -1).replace(/"/g, '');
}
}
// add caption
var captionText = document.getElementById("caption");
// close the modal
var span = document.getElementsByClassName("close")[0];
span.onclick = function() {
modal.style.display = "none";
}
.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;
}
.img {
display: block;
width: 200px;
height: 100%;
margin-right: 10px;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
cursor: pointer;
}
.img-container {
display: flex;
height: 100px;
min-height: 20rem;
}
.modal {
display: none;
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
box-sizing: border-box;
overflow: auto;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0, 0, 0.9);
justify-content: center;
align-items: center;
}
.modal-content {
margin: auto;
display: block;
width: 80%;
max-width: 700px;
max-height: 80%;
object-fit: contain;
-o-object-fit: contain;
animation-name: zoom;
animation-duration: 0.6s;
}
/* Next & previous buttons */
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
-moz-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
width: auto;
padding: 0.8rem;
color: #777;
font-weight: normal;
font-size: 18px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
-webkit-user-select: none;
z-index: 3;
}
.prev:hover,
.next:hover {
color: #000;
}
.next {
right: 0;
}
.prev {
left: 0;
}
#keyframes zoom {
from {
transform: scale(0)
}
to {
transform: scale(1)
}
}
<div class="img-container">
<div id="tehran" class="img" style="background-image: url(https://images.unsplash.com/photo-1524567492592-cee28084482e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=600&q=60)">
</div>
<div id="masuleh" class="img" style="background-image: url(https://images.unsplash.com/photo-1567317255448-8e6c04e22114?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=634&q=80)">
</div>
<div id="zanjan" class="img" style="background-image: url(https://images.unsplash.com/photo-1518727577784-f62f1115eefb?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80)">
</div>
</div>
<!-- The Modal -->
<div id="myModal" class="modal">
<!-- Buttons -->
<span class="close">×</span>
<a class="prev">❮</a>
<a class="next">❯</a>
<!-- Modal Content -->
<img id="modalImg" class="modal-content">
<div id="caption"></div>
</div>