Selecting a specific element and attaching a particular class to this element, but directing it towards a different element that shares the same index in a separate node list

I am working on a project where I have two sets of identical images - one is displayed in a gallery format and the other set is hidden until its corresponding gallery image is clicked, creating a lightbox effect.

For example:

<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 written a script that loops over the gallery images and adds an event listener to each image. The goal is to be able to add a class to the corresponding "modal-image" when a "gallery-image" is clicked.

Both sets of images are in the same order and have matching indexes when retrieved as nodelists using document.getElementsByClassName (with different variable names like galleryImage[0] and modalImage[0]). My question is: Is there a method to automatically add a class to the corresponding "modal-image" when clicking a "gallery-image" using the nodelist?

If anyone has a solution, I would appreciate a detailed explanation of the logic behind it. I have seen examples that involve assigning IDs with index numbers to each image, but I would like to keep all the JavaScript in one file and understand how to work with nodelists effectively.

Thank you for your help!

Answer №1

Your query seems to revolve around the following question: "How can I establish the index of a DOM element within a NodeList, given a reference to the element?" Once you have the index, the process of obtaining the corresponding element in another list becomes straightforward.

To achieve this, you can utilize the array .indexOf() method or employ .call() to apply this method on a NodeList:

var index = Array.prototype.indexOf.call(galleryImages, elementToFind)

The resulting value in index will represent the sought-after element's index. Subsequently, modalImages[index] corresponds to the item in the other list.

In addition, although it diverges from your initial inquiry, instead of attaching click handlers individually to each image, consider linking a single handler to the encompassing UL element. Inside this handler, evaluate the event.target to ascertain whether it belongs to an IMG element. This practice, known as delegated event handling, leverages bubbling of click events through parent elements, enabling management of clicks on gallery IMG elements at the UL level.

For illustrative purposes, upon clicking, I am assigning a selected class that renders the respective item yellow while removing any prior selections.

// Obtain references for the UL elements:
var galleryContainer = document.getElementById("gallery")
var modalContainer = document.getElementById("modal")

// Retrieve lists of IMG elements:
var galleryImages = galleryContainer.querySelectorAll(".gallery-image")
var modalImages = modalContainer.querySelectorAll(".modal-image")

// Attach click handler to the gallery UL:
galleryContainer.addEventListener("click", function(event) {
  // If the click target does not pertain to the specified element, immediately exit
  if (event.target.tagName.toLowerCase() != "img") 
    return
  
  // Check for an existing .selected element; remove its class if present
  var currentSelected = document.querySelector(".selected")
  if (currentSelected)
    currentSelected.classList.remove("selected")
  
  // Determine the index of the current IMG in the list and derive the corresponding item in the alternative list using said index
  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>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Creating a loop in a column-based carousel without using JavaScript

I'm currently working on developing a carousel using JavaScript or jQuery. I've attempted the code snippet below, but I'm having trouble getting it to display in 3 or 4 columns. While I understand that Bootstrap can handle this easily, I&apo ...

Verify whether a group of div elements overlaps a fixed div while scrolling

I have a layout with a list of posts and a logo positioned at the bottom of the page. The issue I am facing is that sometimes the title of the posts and the logo overlap, and I want to set the logo's opacity to 0.25 only when the text from .cat-date i ...

In what way can the button display the permission directly on the page?

When the website notification is granted, a green button should be displayed. If it is denied, show a red button instead. The button comes with a CSS style and a checkbox but does not have the permission to grant or allow any permissions on the page. Butt ...

Retrieve information from child components and populate form fields

Currently, I am working on creating a dynamic form that utilizes a sub component to display input fields because creating them statically would exceed a limit. I pass the states for the form I created along with some data and the change form function. Howe ...

The tablet is having trouble playing the mp3 audio file

When clicking on an mp3 audio file, I want the previous file to continue playing along with the new one. While this works perfectly on browsers with Windows machines, there seems to be an issue when using a tablet. The second mp3 stops playing when I clic ...

Troubleshooting a problem with AJAX returning the data

Currently, I have a javascript function that calls another javascript function called zConvertEmplidtoRowid. This second function utilizes an ajax call to execute a query and retrieve data stored in a variable named rowid. My challenge lies in figuring out ...

Error Encountered: Unable to Locate 'bootstrap' label in Bootstrap 5 Popover

I have been working on implementing a popover in my Angular 12 project using Bootstrap version v5.0.1. However, I am encountering a name error that I can't seem to resolve: var exampleEl = document.getElementById(item.name + index); var tooltip = ne ...

React Material-UI components (Slider/Select) "onChange" event does not update the value instantly, it shows the result of the previous click

My goal is to utilize Slider/Select for capturing user query parameters, which will then trigger changes in the URL (via handleChange) and subsequently make API calls using fetch hooks. However, I've encountered an issue where adjusting the Slider va ...

Mastering the control of a camera in three.js using a combination of keyboard and mouse navigation techniques

I have been working on a 3D environment in WEB GL using three.js, previously using orbitcontrols.js as shown in this project: http://codepen.io/nireno/pen/cAoGI. Recently, I came across a different method of navigating the environment using the W, A, S, D ...

Fulfill the promise in AngularJS and assign it to a different factory

Presenting my factory below: .factory('UserData', ['User', '$q', function(User, $q) { var deferred = $q.defer(); return { user: null, get: function() { var _this = this; _this. ...

Find elements that are not contained within an element with a specific class

Imagine having this HTML snippet: <div class="test"> <div class="class1"> <input type="text" data-required="true"/> </div> <input type="text" data-required="true"/> </div> I'm looking to select ...

Adding a unique value to an array using JQuery when it does not already exist

In need of assistance with a function that is supposed to add values to an array if they do not already exist. var category_json = new Array(); $.ajax({ type: 'POST', url: "<?php ech ...

Using the "number" input type gives the user the ability to easily remove numbers and leave the input field

I have integrated angularJS with rzSlider to provide users the option of manually entering a number value or using the slider to input the value. However, I'm facing an issue where if a user drags the slider and then deletes the entire input from the ...

Upon clicking the link, the JavaScript functionality failed to activate

When I click on a link and try to add a class, it's not working. I want to create a "modal" div. Here is the PHP/HTML code: <?php if(isset($_GET['ido'])) { ?> <div id="modal" class="modal" style="background: blue; width: 1 ...

Surprise mistake: Jade's error with the length

What can I do to address this problem? The jade file in question is as follows: extends layout block content h1. User List ul each user, i in userlist li a(href="mailto:#{user.email}")= user.username U ...

Utilizing the Power of GrapesJs in Vue3

Recently, I attempted to integrate the GrapesJS editor into my Vue.js project, but encountered some difficulties. The editor was not visible in the browser, and the designated tag for the editor appeared empty. Here is my editor configuration: <template ...

Scripts in iframes within webviews are not preloading and executing properly

When using the <webview> tag in the renderer process within the <body> of a web page, the following code is used: <webview src="http://somewebpage.com" preload="somescript.js"> The script somescript.js will be execute ...

Substitute the comma with a space

Here is my input code snippet: (((text(text here))) AND (test3) Near (test4) NOT (test5) NOT (Test6)),((tttt,tttt)),((and,lol)),((hbhbhbhbhbh)) This is the output I get: (((text(text here))) AND (test3) Near (test4) NOT (test5) NOT (Test6) (tttt,tttt) (an ...

Adding a fresh HTML element to a list at a designated location

I found this excellent example on CODEPEN Is there a way to insert a new random number into the list so that it appears after 24 but before 19? Is there an efficient solution or do I need to manually check each li element and determine where to place the ...

An issue arises in Node.js and MongoDB where data is being returned from the previous update instead of the most

Currently, I'm delving into the world of Node.js and creating a platform where individuals can vote on different items and view the results afterward. The voting process involves utilizing the /coffeeorwater POST route, which then redirects to the /re ...