Switch background color multiple times on click using JavaScript loop

Hello amazing people!

I have a container with 52 small boxes and one large box containing a letter. The smaller boxes are arranged around the larger one using CSS grid, and when hovered over, they turn light grey.

My Objective

When any of the 52 small boxes are clicked, the background should first turn green. If clicked again on the same box, it should turn red. While the color is red or green, the hover effect (grey) should be disabled. Clicking for a third time will reset the background to white, re-enabling the grey hover option. Additionally, each box has a data property called "defaultWhite" that I want to change to red or green or back to defaultWhite upon clicking, as the data will later be exported to an excel document.

As I plan to export this data, any assistance in achieving the desired color changes and data updates while clicking would be greatly appreciated! :)

Answer №1

The first step is understanding that the id attribute must be unique for each element, while the class attribute can be reused. Consider swapping your classes and ids.

To manage different states, it's recommended to use distinct classes for each state and toggle between them upon click events.

const changeColor = document.getElementsByClassName('changeColor');

Array.from(changeColor).forEach(function(element) {
  element.addEventListener('click', function(event) {
  item = event.target;
    
    if (item.classList.contains('green')) {
        item.classList.remove('green');
        item.classList.add('red');
    } else if(item.classList.contains('red')) {
        item.classList.remove('red');
        item.classList.add('enableHover');
    } else {
        item.classList.add('green');
        item.classList.remove('enableHover');
    }
  });
});
/* Your CSS code here */

Your HTML structure goes here as well.

Answer №2

It is not allowed to have multiple elements in a document with the same id value.

Using the 'starts with' selector on individual class names can resolve this issue. This method allows for selecting all elements with classes starting with "^she".

When applying a style to the clicked element, the $(this) selector can be used to target the specific element that was clicked.

An object similar to a map can be utilized to store the current state of the clicked element. Using a unique key like "class" ensures differentiation between each element.

const changeColor = document.getElementById('changeColor'),
  colors = ['green', 'red', 'white'];
let colorIndex = 0;
let map = {};
$('[class^="she"]').on('click', function() {
  let classN = $(this).attr('class');
  map[classN] = map[classN] || 0;
  colorIndex = (map[classN]) % colors.length;
  $(this).css("backgroundColor", colors[colorIndex]);
  ++map[classN];
});
html {
  -webkit-font-smoothing: antialiased;
}

body {
  background: #fff;
  margin: 0 auto;
  padding: 1em;
}

.generalWrapper {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 100%;
  background-color: ;
  position:
}

... (CSS code truncated for brevity)

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.0/jquery-ui.min.js"></script>
<div class="generalWrapper">
  <div class="boxes-container">
    <div class="grid-container">
      ... (HTML code truncated for brevity)
    </div>
  </div>
</div>

Answer №3

Encountering a JavaScript issue is not uncommon, and the use of document.getElementById often results in only one record being returned, preventing the binding of click events to all elements. To address this, consider implementing the following solution:

Suggested HTML structure:

var changeColor = $('.changeColor');
colors      = ['green', 'red', 'white'];
let   colorIndex  = 0;

changeColor.click((event) => {
$(event.toElement).css('background-color',colors[colorIndex])     
colorIndex = (colorIndex + 1) % colors.length
}); 
html {
    -webkit-font-smoothing: antialiased;
}

body {
    background: #fff;
    margin: 0 auto;
    padding: 1em;
}

/* CSS styles go here */

<!DOCTYPE html>
<html>  
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>S test</title>
        <meta name="description" content="S test">
        <link rel="stylesheet" href="style.css">
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.0/jquery-ui.min.js"></script>
    </head>
    <body>
    <div class="generalWrapper">  
      <div class="boxes-container">  
        <div class="grid-container">
          <div class="Title">SHE</div>
          <!-- Additional HTML goes here -->
        </div>
      </div> 
    </div>
    </body>
<script type="text/javascript" src="a.js"></script>
</html>

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

Tips for combining two htmlelements together

I have two HTML table classes that I refer to as htmlelement and I would like to combine them. This is similar to the following code snippet: var first = document.getElementsByClassName("firstclass") as HTMLCollectionOf<HTMLElement>; var se ...

Warning: Knex was unable to acquire a connection due to a timeout, resulting in an UnhandledPromiseRejectionWarning

I'm having trouble connecting my Telegram bot to the database using knex. I am working with MySQL, and I have already created the database and tables which are visible on the /phpMyAdmin page. The credentials used for accessing the database in my code ...

What could be the reason that my Javascript function is not displaying in the HTML document?

I'm currently working on developing an HTML page that displays random quotes by Mark Twain. The function and array of quotes are set up in a separate Javascript file which is linked to the main HTML document. However, I am facing an issue where the ou ...

Using Three.js to create smooth rotations for objects

I have a logo in .obj format that I am loading onto a canvas using three.js. The logo is an integral part of the website's loading section that I am currently developing. Within this section, there is a 'Click to Enter' button. My goal is fo ...

What is preventing Firefox and IE from displaying images fully in a list item?

I am trying to create a slideshow with two separate sliders using li elements for that purpose. It works perfectly in Chrome and Safari, but I am encountering issues in Firefox and IE. In Firefox, the slideshow works fine in quirks mode but not in standar ...

Slightly puzzled by the declaration of `var app = express()`

After going over the documentation, I'm still struggling to grasp why we store express() inside an app variable. I attempted to call methods using express().get and .post directly, but was unsuccessful. Why is that? Why doesn't it function in t ...

Whenever I adjust the layout of the navigation bar, the edges end up getting clipped

I'm having trouble with the border shape of my navbar. When I try to make it a rounded pill shape, the edges get cut off instead of being properly displayed. https://i.stack.imgur.com/sUN2Y.png Below is the HTML template: <template> <div cl ...

What advantages can be gained from having multiple package.json files within a single application?

Embarking on the journey of creating my inaugural full react web application entirely from scratch. Previously, I've mainly worked on assignments that were partially pre-made for me. While setting up my project, I couldn't help but notice that I ...

How can we extract word array in Python that works like CryptoJS.enc.Hex.parse(hash)?

Is there a method in Python to convert a hash into a word array similar to how it's done in JavaScript? In JavaScript using CryptoJS, you can achieve this by using: CryptoJS.enc.Hex.parse(hash), which will provide the word array. I've searched ...

Another element concealing an element underneath

I am currently working on a website and could really use some assistance. Being new to web design, I find myself puzzled by this particular issue. The problem I'm facing is with a sawtooth pattern that should be displayed over a header, similar to the ...

The CSS Scroll-Snapping feature seems to be overlooking one specific element that it should be snapping to

Currently, this website is designed to work exclusively for mobile devices. When viewed in Chrome's mobile view using the inspector, everything appears to be functioning correctly. However, when accessed through Safari or on an actual mobile phone, th ...

Looking for repeating values in inputs excluding this one

In the midst of a medium-sized project, an issue has arisen. I have condensed the core problem into this code snippet. Here's what the code does: $(".6").focusout(function(){ if( $(".6").filter(function(){ return this.value;}).not(this).length>0 ...

Is it necessary to encapsulate Factory calls within a function in my Controller file?

Typically, I call a Factory from my Angular controller directly within the controller function without creating a separate method. For instance: (function () { 'use strict'; angular.module("Dashboard") .controller("DashboardController", D ...

Tips for utilizing Jquery webcam on mobile devices like Android and iPhone

Currently, I am in the process of developing mobile web applications utilizing jquery mobile and HTML 5. I am working on a feature that requires access to the camera. In order to achieve this functionality, I have integrated the following plugin: While ...

Oops! Looks like there's an issue with the NextJS Custom Carousel bug. The error message reads: ReferenceError: document is not defined and is unable to read properties of undefined (

I have developed a unique carousel component to showcase text testimonials from scratch. The custom carousel utilizes a specialized script, carouselFunction.js, for navigational functionality to cycle through each testimonial. Here is an image of the carou ...

Alignment problem with email signatures on MAC devices

Recently, I designed a straightforward email signature and successfully copied and pasted it into the appropriate section. However, while it works perfectly in Outlook, there is an issue with MAC Mail (Version 7.3) where the image extends beyond the table. ...

The starting point of an html text is signified by < and it concludes with >, showcasing

My HTML <div> <Sample text> </div> <div> <SampleText> </div> In both examples above, blank content is appearing after the DOM is created. I anticipate displaying the text as it appears. Your assistance with this matt ...

Utilizing the essential "required" attribute in HTML5 in conjunction with a submit Button

I'm encountering a frustrating issue with a form. I typically use the 'required' attribute in an input box for quick validation, but when I switch to using a button instead, the validation doesn't seem to work. Is it possible that the & ...

Steps for determining the total count of elements in a SQLite table using PhoneGap

I am struggling to accurately count the number of elements in a table in SQLite. The current code I have is not producing the correct result. Can you please advise on how to achieve this? function Test(test){ alert(test) var x; db.transaction(functi ...

Is there a way to check the existence of an email in the database without having to refresh the PHP page?

Currently, I am using the following method to validate my inputs: <form method="post"> <label>Email</label> <input type="email" name="user_email"> <input type="submit" name="reg"> </form> if(isset($_POST['reg' ...