Tap on a division to alternate the class of an image

I'm facing a problem with changing an icon when I click on a div. I'm trying to create an accordion element with an arrow icon (using Iconoir) that switches between classes "iconoir-nav-arrow-right" and "iconoir-nav-arrow-down" each time it's clicked.

It seems like the icon is being toggled in the div through classList toggle, but not actually changing the class of the img with the class "arrowAcc". I'm unsure how to target the img when clicking on the div. Would appreciate any help or guidance on this issue. Thanks in advance!

The code (js, css, html):

function toggleIconAcc(element) {
  element.classList.toggle("iconoir-nav-arrow-right");
  element.classList.toggle("iconoir-nav-arrow-down");
}

var acc = document.getElementsByClassName("accordion");
var i;

for (i = 0; i < acc.length; i++) {
  acc[i].addEventListener("click", function () {
    this.classList.toggle("active");
    var panelAccordion = this.nextElementSibling;
    if (panelAccordion.style.maxHeight) {
      panelAccordion.style.maxHeight = null;
    } else {
      panelAccordion.style.maxHeight = panelAccordion.scrollHeight + "px";
    }
  });
}
:root {
    --Lato: "Lato", sans-serif;
    --WorkSans: "Work Sans", sans-serif;
    --hover-color: #084f58;
    --third-color: #028090;
    --fourth-color: #D7FAFE;
    --text-color: #2e2e2e;
    --bggradient: #fffdf5;
    --bggradient2: linear-gradient(220.55deg, #665da1 0%, #418CB7 100%);
    --light-gray: rgba(255, 255, 255, 0.877)
}

#faq {
    display: flex;
    max-width: 55%;
    margin: auto;
    flex-direction: column;
    padding-top: 16vmin;
}

#faq h1 {
    text-align: center;
    color: var(--text-color);
    font-family: var(--WorkSans);
    font-weight: 300;
    font-size: 24px;
}

.accordion {
    display: flex;
    align-items: center;
    background-color: var(--fourth-color);
    color: var(--text-color);
    font-family: var(--WorkSans);
    cursor: pointer;
    border-radius: 8px;
    border: none;
    padding: 12px;
    width: 100%;
    height: 60px;
    text-align: left;
    transition: 0.25s;
    outline: none;
    margin-top: 4px;
}


.active,
.accordion:hover {
    background-color: var(--hover-color);
    color: #f3f3f3;
}

.panelAccordion {
    padding: 0 18px;
    font-size: 14px;
    background-color: var(--bggradient);
    overflow: hidden;
    max-height: 0;
    transition: max-height 0.2s ease-out;
}
<head>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/lucaburgio/iconoir@master/css/iconoir.css">
</head>                        
                                                <div id="faq">
                            <h1>Frequently asked questions</h1>
                            <div onclick="toggleIconAcc(this)" class="accordion">
                                <i class="iconoir-nav-arrow-right arrowAcc"></i>
                                <h4>Lorem ipsum dolor sit amet, consectetur adipisicing?</h4>
                            </div>
                            <div class="panelAccordion">
                                <p class="section-text">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Saepe
                                    quia asperiores
                                    harum! Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequuntur nobis
                                    enim voluptate fugiat officiis similique!
                                </p>
                            </div>
                            <div onclick="toggleIconAcc(this)" class="accordion">
                                <i class="iconoir-nav-arrow-right arrowAcc"></i>
                                <h4>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Rerum
                                    numquam atque enim?</h4>
                            </div>
                            <div class="panelAccordion">
                                <p class="section-text">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dicta
                                    fuga dolore fugiat itaque, a provident. Iste ea optio corporis nostrum, hic
                                    excepturi, ab veritatis iure consequatur sint saepe, distinctio blanditiis
                                    architecto dolorum deleniti.</p>
                            </div>
                            <div onclick="toggleIconAcc(this)" class="accordion">
                                <i class="iconoir-nav-arrow-right arrowAcc"></i>
                                <h4>Lorem ipsum dolor sit amet?</h4>
                            </div>
                            <div class="panelAccordion">
                                <p class="section-text">Lorem ipsum dolor, sit amet consectetur adipisicing elit.
                                    Repudiandae provident iusto quae? Lorem ipsum dolor sit amet consectetur adipisicing
                                    elit. Earum tenetur id sapiente amet molestiae assumenda saepe perspiciatis quia quo
                                    deserunt aliquam nemo, aspernatur aperiam tempore excepturi commodi debitis autem
                                    esse! Eum, a.
                                    harum!</p>
                            </div>
                            <div onclick="toggleIconAcc(this)" class="accordion">
                                <i class="iconoir-nav-arrow-right arrowAcc"></i>
                                <h4>Lorem ipsum dolor sit amet?</h4>
                            </div>
                            <div class="panelAccordion">
                                <p class="section-text">Lorem ipsum dolor, sit amet consectetur adipisicing elit.
                                    Repudiandae provident iusto quae? Lorem ipsum dolor sit amet consectetur adipisicing
                                    elit. Earum tenetur id sapiente amet molestiae assumenda saepe perspiciatis quia quo
                                    deserunt aliquam nemo, aspernatur aperiam tempore excepturi commodi debitis autem
                                    esse! Eum, a.
                                    harum!</p>
                            </div>
                            <div onclick="toggleIconAcc(this)" class="accordion">
                                <i class="iconoir-nav-arrow-right arrowAcc"></i>
                                <h4>Lorem ipsum dolor sit amet?</h4>
                            </div>
                            <div class="panelAccordion">
                                <p class="section-text">Lorem ipsum dolor, sit amet consectetur adipisicing elit.
                                    Repudiandae provident iusto quae? Lorem ipsum dolor sit amet consectetur adipisicing
                                    elit. Earum tenetur id sapiente amet molestiae assumenda saepe perspiciatis quia quo
                                    deserunt aliquam nemo, aspernatur aperiam tempore excepturi commodi debitis autem
                                    esse! Eum, a.
                                    harum!</p>
                            </div>
                        </div>

Answer №1

Your javascript code has been modified to utilize addEventListener instead of inline code.

An issue in your current code is the presence of two click handlers for the accordion element, one in the javascript and the other inline, both targeting the same element.

By streamlining this and using just one click handler, you will be able to resolve the issues you are facing.

Furthermore, ensure that the iconoir-nav-arrow-right class is toggled on the icon itself, not the accordion div as previously done with the inline javascript click handler.

var acc = document.querySelectorAll(".accordion");

acc.forEach(function(el) {
  el.addEventListener("click", function(e) {
    this.classList.toggle("active");
    let icon = this.querySelector("i");
    icon.classList.toggle("iconoir-nav-arrow-right");
    icon.classList.toggle("iconoir-nav-arrow-down");
    let panelAccordion = this.nextElementSibling;
    if (panelAccordion.style.maxHeight) {
      panelAccordion.style.maxHeight = null;
    } else {
      panelAccordion.style.maxHeight = panelAccordion.scrollHeight + "px";
    }
  });
});
:root {
  --Lato: "Lato", sans-serif;
  --WorkSans: "Work Sans", sans-serif;
  --hover-color: #084f58;
  --third-color: #028090;
  --fourth-color: #D7FAFE;
  --text-color: #2e2e2e;
  --bggradient: #fffdf5;
  --bggradient2: linear-gradient(220.55deg, #665da1 0%, #418CB7 100%);
  --light-gray: rgba(255, 255, 255, 0.877)
}

#faq {
  display: flex;
  max-width: 55%;
  margin: auto;
  flex-direction: column;
  padding-top: 16vmin;
}

#faq h1 {
  text-align: center;
  color: var(--text-color);
  font-family: var(--WorkSans);
  font-weight: 300;
  font-size: 24px;
}

.accordion {
  display: flex;
  align-items: center;
  background-color: var(--fourth-color);
  color: var(--text-color);
  font-family: var(--WorkSans);
  cursor: pointer;
  border-radius: 8px;
  border: none;
  padding: 12px;
  width: 100%;
  height: 60px;
  text-align: left;
  transition: 0.25s;
  outline: none;
  margin-top: 4px;
}

.active,
.accordion:hover {
  background-color: var(--hover-color);
  color: #f3f3f3;
}

.panelAccordion {
  padding: 0 18px;
  font-size: 14px;
  background-color: var(--bggradient);
  overflow: hidden;
  max-height: 0;
  transition: max-height 0.2s ease-out;
}
<head>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/lucaburgio/iconoir@master/css/iconoir.css">
</head>
<div id="faq">
  <h1>Frequently asked questions</h1>
  <div class="accordion">
    <i class="iconoir-nav-arrow-right arrowAcc"></i>
    <h4>Lorem ipsum dolor sit amet, consectetur adipisicing?</h4>
  </div>
  <div class="panelAccordion">
    <p class="section-text">Lorem ipsum dolor sit, amet consectetur adipisicing elit. Saepe quia asperiores harum! Lorem ipsum dolor sit amet consectetur adipisicing elit. Consequuntur nobis enim voluptate fugiat officiis similique!
    </p>
  </div>
  <div class="accordion">
    <i class="iconoir-nav-arrow-right arrowAcc"></i>
    <h4>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Rerum numquam atque enim?</h4>
  </div>
  <div class="panelAccordion">
    <p class="section-text">Lorem ipsum dolor sit amet consectetur, adipisicing elit. Dicta fuga dolore fugiat itaque, a provident. Iste ea optio corporis nostrum, hic excepturi, ab veritatis iure consequatur sint saepe, distinctio blanditiis architecto dolorum deleniti.</p>
  </div>
  <div class="accordion">
    <i class="iconoir-nav-arrow-right arrowAcc"></i>
    <h4>Lorem ipsum dolor sit amet?</h4>
  </div>
  <div class="panelAccordion">
    <p class="section-text">Lorem ipsum dolor, sit amet consectetur adipisicing elit. Repudiandae provident iusto quae? Lorem ipsum dolor sit amet consectetur adipisicing elit. Earum tenetur id sapiente amet molestiae assumenda saepe perspiciatis quia quo deserunt aliquam nemo,
      aspernatur aperiam tempore excepturi commodi debitis autem esse! Eum, a. harum!
    </p>
  </div>
  <div class="accordion">
    <i class="iconoir-nav-arrow-right arrowAcc"></i>
    <h4>Lorem ipsum dolor sit amet?</h4>
  </div>
  <div class="panelAccordion">
    <p class="section-text">Lorem ipsum dolor, sit amet consectetur adipisicing elit. Repudiandae provident iusto quae? Lorem ipsum dolor sit amet consectetur adipisicing elit. Earum tenetur id sapiente amet molestiae assumenda saepe perspiciatis quia quo deserunt aliquam nemo,
      aspernatur aperiam tempore excepturi commodi debitis autem esse! Eum, a. harum!
    </p>
  </div>
</div>

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

Ways to display the content of a specified URL in a new window for printing using JavaScript, jQuery, or ASP

Is there a way to open a URL in a new window as a print window rather than a normal window? I know how to open a new window using window.open(url); but I specifically need it to be a print window. ...

Utilize the dropdown menu across all table cells in a table

My p-table has a unique feature - the last column contains three dots that trigger a dropdown menu when clicked. The only issue is that the fixed position of the dropdown menu does not align properly with the td element in each row. Check out the HTML cod ...

Code displayed on Facebook when sharing a website link implemented in JavaScript

Is there a way to prevent javascript code from appearing in Facebook posts when sharing links, whether it's done manually or through programming? I'm specifically looking for solutions to fix my website so that when I post links on Facebook, the ...

Creating an Efficient React Portal Component

Having trouble rendering an input field within a portal. Whenever I change the value of the input, it loses focus. I suspect this is happening due to re-rendering upon state change. Link to code sandbox Any suggestions for a solution? UPDATE Is there a ...

Creating a SAS URL for Azure Blob storage in Node.js using the generateBlobSASQueryParameters method from the @azure/storage-blob module

Hello, I am working with an Azure storage account where I upload and create a SAS URL to download images. Below is the code snippet that I have used: const { BlobServiceClient, StorageSharedKeyCredential, BlobSASPermissions, generateBlobSASQueryPar ...

When given an input, the initial state will rise from 0.00 to 0.01, and with each subsequent input, it will further increase to 0

My question revolves around managing an input field in React. Initially, the input has a value of 0.00. When a user enters a number, such as 1, the new value should be 0.01. Subsequently, if the user enters another number, for example, 1 again, the updated ...

Using HTML nested lists in Wordpress sites

Working on nested, ordered lists using ol types and encountering an issue where the code appears correctly in Wordpress preview but displays incorrectly in Firefox and IE. The lists are showing as numbered instead of the specified types in the code provide ...

Displaying truncated title text

Would it be feasible to display clipped text (overflow: hidden) in a way that is fully readable when hovered over? An attempt like this: div:hover { overflow: visible; background-color: yellow; } results in the text overlapping, making it impossible ...

Employing the next function in conjunction with an Express server during development

I currently have an express server handling my back-end operations. I am now in the process of transitioning my front-end to nextJS and would like to set up a proxy for my nextJS requests to access the port that my back-end is running on. Is it possible to ...

Is there a way to incorporate arguments into my discord.js commands?

Hey there! I'm looking to enhance my Discord commands by adding arguments, such as !ban {username}. Any tips or guidance on the best approach for this would be amazing! const Bot = new Discord.Bot({ intents: ["GUILD_MESSAGES", "GUIL ...

Do we need to utilize a server folder in Nuxt 3 if we have API endpoints?

In Nuxt 3, there is a dedicated server folder containing an api subfolder. Why should we utilize this when we already have API endpoints built with a server-side programming language like Laravel? Are they linked in any way? For instance, consider these ...

The data that has been retrieved is not currently displayed within the Vue table

I'm currently exploring js/vue and I'm attempting to retrieve data from an API. There's a field where the value is used to fetch data from the API based on that keyword. When I check the console log, I can see that the data is being received ...

Setting up an image DIV for a dynamic overlay effect

Here is a JSFiddle that works correctly with fixed height and width: http://jsfiddle.net/69td39ha/2/. The animation activates correctly when hovered over. I attempted to adapt the above example to be responsive without fixed dimensions. However, I'm ...

The issue of NextAuth in connection with Spotify failing to display the user's profile picture

I have recently implemented NextAuth v4 and encountered an issue after authenticating with Spotify. Despite successfully retrieving user information from Spotify, I seem to be missing access to the user's profile picture. Here is the data I receive fr ...

How can you convert an array into a string by including the numerical values of each element within the array?

var array = ['a', 'b', 'c'] function arrayTransform(array) { if (array.lengths === 0) { console.log("Empty") } else { console.log(array.join()); } } arrayTransform(array); The expected result should be 1.a, 2.b ...

Rendering a page using React and NextJS with server-side rendering to retrieve and showcase dynamic data

At the moment, I am utilizing client-side rendering on a page that fetches data via an API and then presents this raw data. 'use client' import React, { useState, useEffect } from 'react' import axios from 'axios'; const Sol ...

Is it possible to add a click event to a table row that contains an input checkbox, without interfering with the ability to click the checkbox itself?

I have a table: <table> <tr> <td>Something</td> <td>Something Else</td> <td><input type='checkbox' value='clickme' id='yes'></td> </tr> When a user ...

Toggle Visibility of Div Based on Matching Class Name When Clicked

Just delving into the world of jQuery and could use some guidance. Is there a way to show a div with a matching class when a specific button is clicked? For example, clicking on a button with the class '.project1' should display the corresponding ...

Is there a method to access the output of getStaticProps function from NextJS API routes?

Is there a method to compute and cache new data during build time that is essential for both the front-end and back-end API routes? I'm looking for a way to access the static properties generated by API routes at build time since the routes are access ...

Can a JSON interface be integrated into a c# application?

I have successfully created a basic C# application (.Net 4.0 + WPF) that is capable of sending and receiving JSON messages through TCP sockets. Now, I am looking to enable JavaScript applications on websites and PHP scripts to communicate with my app by s ...