I have 2 sets of the same images. 1 is the gallery another is the list of images that are display: none; until the corresponding image is clicked. (essentially a light box)
eg:
<ul id="gallery">
<li><img class="gallery-image" src="dog"></li>
<li><img class="gallery-image" src="cat"></li>
<li><img class="gallery-image" src="rabbit"></li>
</ul>
<ul id="modal">
<li><img class="modal-image" src="dog"></li>
<li><img class="modal-image" src="cat"></li>
<li><img class="modal-image" src="rabbit"></li>
</ul>
I have looped over images in the gallery and added an even listener to each img.
These images are in the same order in both lists and have the same index when i use document.getElementsByClassName and am returned the nodelist. (both have different variable names. eg galleryImage[0] and modalImage[0]) Is there a way for me add a class to the corresponding "modal-image" when clicking a "gallery-image" using the node list? Essentially when galleryImage[0] is closed I want to add a class to modalImage[0].
Are there methods to do this? What is the approach to take?
I have found examples and have been given "answers" but so far all include assigning an id with an index number to each image and would prefer to have all the js in 1 file and keep both tidy and also learn how to play with nodelists.
Also would appreciate if someone can explain their answer to understand the logic behind it rather than an "answer"
Thank you in advance
Seems to me that your question boils down to this: "Given a reference to a DOM element, how can I determine its index in a NodeList?" Because the second part about getting the corresponding element in another list is simple once you have the index.
So you can use the array .indexOf()
method to find the index of an item within an array, or via .call()
you can use that method on a NodeList:
var index = Array.prototype.indexOf.call(galleryImages, elementToFind)
...after which index
will be the index of the element you're looking for. (Or -1 if it wasn't found, but in your case you know it will be found.) So then modalImages[index]
is the corresponding item in the other list.
Also, not what you're asking about, but rather than binding click handlers to every image in a loop, I would bind a single handler to the containing UL element, and within that handler test the event.target
to see if it was an IMG element. This is called delegated event handling: click events on elements "bubble up" through their containing elements, so clicks on any of your gallery IMG elements can be handled at the level of the UL.
For demonstration purposes, on click I'm assigning a selected
class that make the corresponding item yellow (and removing any previous selection).
// Get references to the UL elements:
var galleryContainer = document.getElementById("gallery")
var modalContainer = document.getElementById("modal")
// Get the lists of IMG elements:
var galleryImages = galleryContainer.querySelectorAll(".gallery-image")
var modalImages = modalContainer.querySelectorAll(".modal-image")
// Bind click handler to gallery UL:
galleryContainer.addEventListener("click", function(event) {
// If the target of the click wasn't an element we care about just return immediately
if (event.target.tagName.toLowerCase() != "img")
return
// Check for a current .selected element, and if it exists remove the class from it
var currentSelected = document.querySelector(".selected")
if (currentSelected)
currentSelected.classList.remove("selected")
// Find the index of the current IMG in the list, and use that index
// to get the corresponding item in the other list
var index = Array.prototype.indexOf.call(galleryImages, event.target)
modalImages[index].classList.add("selected")
});
.selected { background-color: yellow; }
<ul id="gallery">
<li><img class="gallery-image" src="dog" alt="dog"></li>
<li><img class="gallery-image" src="cat" alt="cat"></li>
<li><img class="gallery-image" src="rabbit" alt="rabbit"></li>
</ul>
<ul id="modal">
<li><img class="modal-image" src="dog" alt="dog"></li>
<li><img class="modal-image" src="cat" alt="cat"></li>
<li><img class="modal-image" src="rabbit" alt="rabbit"></li>
</ul>