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

What is the best way to extract user input and pass it to an AJAX request URL?

Recently, I successfully completed an AJAX request using AngularJS. You can check out the code here. Everything was working perfectly until I tried to add a dynamic variable (city) to the link like this: $http.get('http://api.wunderground.com/api/KEY ...

Tips for implementing code to function across several images in HTML and CSS

Hey there, I'm currently working on a website project for my friend and I sometimes refer to www.w3schools.com for help with coding. I'm having trouble implementing a gallery feature where users can click on images to view them fullscreen. I foun ...

Is there a way to determine if a table cell contains overflowing text compared to another cell?

Is there a way to detect if the content of the fourth td overflows from the second td? I am looking for a method to determine which td has overflowed text and identify which td's text is overflowing. What approach can be used to determine which td i ...

What causes the discrepancy in CSS display between production and development environments in Material-UI?

Using material UI (verison: ^4.12.3) Select, with a customized input has led to an unexpected issue in the production environment. The Select input in prod has a black background and a :before element with a white background that I didn't intend to ha ...

Limiting a text based on spaces or at the completion of a word within a string or sentence

Currently, I am utilizing a LimitTo filter to generate excerpts of article descriptions for display on the homepage of a website as snippets in the feature section. The LimitTo filter is set at a maximum of "100 characters," but it sometimes cuts off word ...

Angular connecting to the count of filtered items

Here's the array I'm working with: [ { type: "hhh", items: [ { "name": "EGFR", "type": "a", "selected": true } ] }, { type: "aaa", items: [ { ...

Using jQuery in Angular, you can add a div element to hidden elements by appending

So, I have a hidden div that I want to show on button click. And not only do I want to show it, but I also want to append another div to it. The show and hide functionality is working fine, but the appending part seems tricky when dealing with hidden eleme ...

Transform nested properties of an object into a new data type

I created a versatile function that recursively converts nested property values into numbers: type CastToNumber<T> = T extends string ? number : { [K in keyof T]: CastToNumber<T[K]> }; type StringMap = { [key: string]: any }; const castOb ...

How can we use jQuery to change the format of a

I'm working on a project where I want the calendar to display the date that the user picks. Right now, my "{{date}}" is in the format 2016-01-11, but it keeps showing one day before the selected date. I would like it to display as mm/dd/yyyy. I belie ...

uncertainty when implementing ng-if / ng-show / ng-hide

I am facing an issue with exporting content to PDF from my HTML. When a user clicks on the export button, the PDF is downloaded, but there are certain divs whose content I do not want to be exported or shown in the PDF. However, I still want them to be vis ...

Strange appearance of Material UI input field

https://i.stack.imgur.com/az6wt.png Does anyone have an idea why this problem is occurring? When using material UI, the default value and label for the field seem to be overlapping. Below is the code for rendering the fields: {formSchema.map((element, i ...

A comprehensive guide to effectively formatting Recharts in React: addressing alignment and size management!

While attempting to style two graphs as floating cards, I am encountering difficulties in controlling the sizing and centering of the graphs. Specifically, I am having trouble with the pie chart in this example. To address this issue, I am passing paramete ...

The onclick event seems to be malfunctioning on the website

My goal is to implement a modal box that appears when a user clicks a button and closes when the user interacts with a close button within the modal box. I have created two functions for this purpose: check() : This function changes the CSS of an element ...

Tips for integrating html2canvas with Vue JS?

One hurdle I encountered was the absence of a shorthand for document.getElementById in Vue. To address this, I created a custom function similar to this one. Another challenge I am currently grappling with is the perceived limitations of the html2canvas do ...

Tips for ensuring the border matches the size of the image

I am in the process of creating a website that includes a filter option. My plan is to have the filters displayed on the left side and the items on the right side. To achieve this layout, I have implemented a scrollable div for the items. However, I notic ...

What is the most effective method for populating data within a browser window?

I have a list of files stored in $scope.data that I retrieved from the searchFactory. Now, my goal is to display these files in the browser window. How can I accomplish this task? ctrl.js $scope.displayFiles = function (){ $window.open($scope.dat ...

ToggleClass is not being applied to every single div

I am currently designing a pricing table with hover effects. You can view the progress here: Upon hovering on a pricing table, all the divs are toggling classes which is not the desired behavior. I want each element to have its own separate interaction. ...

Switch between different react components

When a component is opened, I want all other components to close. Whenever they are clicked, they will display a list. class ParentComponent extends Component{ constructor(props){ super(props) this.state= {...} } render(){ return( ...

The app.get() method in Node JS and Express requires three parameters, and I am seeking clarification on how these parameters work

Hey there, I'm new to this and have a question regarding my code using passport-google-oauth20. app.get('/auth/google/secrets', passport.authenticate('google',{failureRedirect: '/login'}), function(req,res){ res.redirec ...

Accessing web authentication through VBA

Having some difficulties trying to access my webtext account through VBA. The first hurdle I faced was identifying the tags for the username and password input boxes. After using inspect elements, it seems like the tags are "username" and "password." Howe ...