Ways to dynamically assign a class to a single element within a group of identical elements

I have three identical items in the DOM. Specifically, I am referring to a moving line

<span class="caret"></span>

<ul>
  <li class="nav-item-1">
   <a href="#">ITEM 1</a>  
   <span class="caret"></span>
  </li>  
</ul>

<ul>
  <li class="nav-item-2">
   <a href="#">ITEM 2</a>  
   <span class="caret"></span>
  </li>  
</ul>

<ul>
  <li class="nav-item-3">
   <a href="#">ITEM 3</a>  
   <span class="caret"></span>
  </li>  
</ul>

Scenario: When I click on the first

<span class="caret"></span>
, it should receive the class "open", while the others remain with only the class "caret". When I click on the second
<span class="caret"></span>
, it should also receive the class "open", and the first one should lose this class. Is this achievable? My attempted solution is as follows:

$(".caret").click(function () {
  $(this).data('clicked', true);
  if ($('.caret').data('clicked')) {
    $(".caret").toggleClass('opened');
  }
});

Although this solution works, it applies the toggleClass('opened') to all elements with the class "caret" instead of just the one that was clicked.

Answer №1

Initially, you correctly utilized $(this) but then resorted back to using $('.caret'). Here is the amended solution:

$(".caret").click(function () {
     $(this).toggleClass('opened');
});

The asker has requested to close all other instances of .caret classes:

$(".caret").click(function () {
    $(".caret").removeClass('opened');
    $(this).addClass('opened');
});

Answer №2

Your HTML code contains errors that will result in incorrect display of the markup in the browser. Without knowing your desired outcome, I am unable to provide a specific solution for fixing it. However, once you address the issues, the basic code structure should be as follows:

$('.caret').on('click', function () {
    $('.caret.opened') 
      .not(this) 
      .removeClass('opened'); 
    $(this)
      .toggleClass('opened'); 
});

If you want one caret to always remain open:

$('.caret').on('click', function () {
    $('.caret.opened') 
      .removeClass('opened'); 
    $(this)
      .addClass('opened'); 
});

Answer №3

I have a hunch that maybe you intended this

It is not considered valid HTML to have a span within a ul tag

$(".nav-item a").on("click",function(e) {
  e.preventDefault();
  $(".caret").removeClass('opened');
  $(this).next(".caret").addClass('opened'); // could toggle if needed
});
.caret::after { content: "🡁" }
.opened::after { content: "🠿" }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
  <li class="nav-item" id="nav-1"><a href="#">ITEM</a><span class="caret"></span></li>
</ul>
<ul>
  <li class="nav-item" id="nav-2"><a href="#">ITEM</a><span class="caret"></span></li>
</ul>

<ul>
  <li class="nav-item" id="nav-3"><a href="#">ITEM</a><span class="caret"></span></li>
</ul>

Answer №4

If you are not already using jQuery in your project, it is not necessary for this particular task.

const navItems = [...document.querySelectorAll("[class^=nav-item-")];

navItems.forEach(item => {
  item.addEventListener("click", () => {
    const opened = document.querySelector(".opened");

    if (opened) {
      opened.classList.remove("opened");
    }

    item.parentElement.querySelector(".caret").classList.add("opened");
  });
});
/* This code is for demonstration purposes only */

.caret.opened:after {
  content: "opened";
}
<ul>
  <li class="nav-item-1">
    <a href="#">ITEM</a>
  </li>
  <span class="caret"></span>
</ul>
<ul>
  <li class="nav-item-2">
    <a href="#">ITEM</a>
  </li>
  <span class="caret"></span>
</ul>
<ul>
  <li class="nav-item-3">
    <a href="#">ITEM</a>
  </li>
  <span class="caret"></span>
</ul>

Answer №5

There are some errors in the HTML code that need to be fixed. The correct syntax should look something like the example below. Let's also incorporate CSS to display what a caret looks like.

Then, we can use JavaScript to handle the toggle functionality.

$("ul").click(function (e) {
  var caret = $(this).find('.caret');
  $('.caret').data('clicked', false);
  $('.caret').removeClass('opened');

  caret.data('clicked', true);
  caret.toggleClass('opened');
});
.caret {
  background-color: red;
  border: 1px solid blue;
  width: 10px;
  height: 10px;
  display: none;
}

.opened {
  display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
  <li class="nav-item-1">
    <a href="#">ITEM</a>
    <span class="caret"></span>
  </li>    
</ul>

<ul>
  <li class="nav-item-2">
    <a href="#">ITEM</a>
    <span class="caret"></span>
  </li>    
</ul>

<ul>
  <li class="nav-item-3">
    <a href="#">ITEM</a>
    <span class="caret"></span>
  </li>    
</ul>

Answer №6

Kindly double check your HTML tag for errors
ensure anchor closing tags are not missed out
include the .nav class in each li element

$(".nav").on('click', function() {
    if ($(this).next('.caret').hasClass('clicked opened')) {
        $('.caret').removeClass('clicked opened');
    } else {
        $('.caret').removeClass('clicked opened');
        $(this).next('.caret').addClass('clicked opened');
    }
});

https://jsfiddle.net/n56b84t9/2/

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

I recently designed a form using a combination of HTML and JavaScript in order to display different dialogues depending on the number of selections made. Unfortunately, the alert function does not seem to be functioning

The concept is to have users select options and then receive employment sector suggestions based on their selections. <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...

The Tailwind style did not completely translate when applied to the content of dangerouslySetInnerHtml

I have an HTML file containing Tailwind styles stored in my database, which needs to be fetched first. This will result in an HTML string that will be inserted into dangerouslySetInnerHtml. Here is the code snippet (utilizing Qwik): export const useHTML = ...

Javascript error specific to Internet Explorer. Can't retrieve the value of the property 'childNodes'

After removing the header information from the XML file, the issue was resolved. Internet Explorer did not handle it well but Firefox and Chrome worked fine. An error occurred when trying to sort nodes in IE: SCRIPT5007: Unable to get value of the proper ...

Choose a child of a parent by specifying the index

:nth-child() - serves as a selector that targets every element which is the nth child of its parent. Is there a method to select a specific child of a parent using an index value? I need to access and modify each child's attributes separately. The o ...

Ways to parse the data from a response received from an Axios POST request

After sending the same POST request using a cURL command, the response I receive is: {"allowed":[],"error":null} However, when I incorporate the POST request in my code and print it using either console.log("response: ", resp ...

Can you explain the concept of "cascading" within CSS?

Can someone kindly explain the specific definition of "Cascading" in Cascading Style Sheets (CSS)? I have heard conflicting perspectives on this topic, so I am seeking clarification here. Any examples to illustrate would be greatly appreciated. ...

Application crash imminent, alert: Uncaught TypeError detected - Unable to access property 'some' of undefined within React

My application has 3 sections. The first section consists of a form where users fill in details about watches, and the data is submitted using the submitHandler function. In the second part, users can enter watches from the first section. When a user click ...

What is the role of the app.use method in ExpressJS in handling URL redirects that end with a "/"?

This script automatically redirects URLs that end with a "/" to the same URL without it. For example, if a user visits http://localhost:3000/about/, they will be directed to http://localhost:3000/about. This ensures that image URLs and other HTML file refe ...

Iconic Side Navigation with collapsed button malfunctioning due to negative positioning

I'm facing two issues with my webpage. First: I have three buttons on the right side of my page that are supposed to behave like the buttons on this example. However, when you scroll, you can see that their position is incorrectly displayed "outside" ...

A unique way to present data: An HTML table featuring four fixed columns with horizontal scrolling

I've been having difficulty creating a table with fixed first four columns while allowing the rest to scroll horizontally. I came across this example first column fixed Although the example has the first column fixed, I'm struggling to extend it ...

Having trouble resolving the FancyBox Jquery conflict and unable to find a solution

Attempting to implement FancyBox on a website. The demo is functional, proving its capability. Yet, encountering an error when trying to integrate it within the WordPress theme: Uncaught TypeError: $(...).fancybox is not a function The header file cont ...

AngularJS nested menu functionality not functioning properly

I am currently working on a nested menu item feature in AngularJS. I have a specific menu structure that I want to achieve: menu 1 -submenu1 -submenu2 menu 2 -submenu1 -submenu2 angular.module('myapp', ['ui.bootstrap']) .cont ...

Efficient Error Handling in Next.JS with Apollo GraphQL Client

Although the component successfully renders the error state, an uncaught exception is displayed in the console and a dialogue box appears in the browser. How can expected errors be handled to prevent this behavior? import { useMutation, gql } from "@a ...

When changing the dropdown option on a separate page in React/Next JS, all checkboxes show the clicked style as a result of utilizing useState

I have implemented checkboxes for three different categories: "Types", "Price", and "Categories". They function correctly, with data being passed to a separate checkbox component without any issues. The problem arises when I click a checkbox and then inte ...

both modules loading at the same time in AngularJS

var moduleA=angular.module("MyModuleX",[]); moduleA.controller("MyControllerX",function($scope){ $scope.name = "John X"; }); var moduleB=angular.module("MyModuleY",[]); moduleB.controller("MyControllerY", function($scope) { $scope.name = "Sarah Y" ...

The additional values inserted into the form using jQuery are not being recognized or passed to AngularJS

My form has multiple input fields, some of which are pre-populated when the markup is generated. For example, value=#{ session[:lat] } or simply value='111'. While this appears correct when inspecting the page, Angular does not submit this value. ...

The ajax success() function is failing to function properly when attempting to make a call

The button's onClick() event is not navigating anywhere. There seems to be an issue with the success() function of the ajax call. Unfortunately, I am new to this and unable to pinpoint the problem. var currentAuthor=""; var currentQuote=""; $(documen ...

Locating the jQuery element just one element next to it

Having set up my HTML like this. <div id="wrap"> <div class="left"></div> <div class="right"> <a href="#">link</a> </div> <div class="listings" style="display:none"> <ul> ...

Is it possible to create a return type structure in TypeScript that is determined by the function's argument?

I'm currently stuck on developing a function that takes a string as an argument and outputs an object with this string as a key. For example (using pseudo code): test('bar') => {bar: ...} I am facing difficulties in ensuring the correct ...

Utilizing jQuery for dynamic horizontal positioning of background images in CSS

Is there a way to set only the horizontal background property? I've tried using background-position-x and it works in Chrome, Safari, and IE, but not in Firefox or Opera. Additionally, I would like to dynamically set the left value of the position. ...