简体   繁体   中英

How to reset all buttons colour back to its original and add a new specific colour when a specific button is clicked?

I am trying to make my buttons change colour when clicked. The easy button turns green, medium turns yellow, hard turns red and insane turns black. When I click any button on the first try it works however when I click on another button it is supposed to reset all the buttons back to white and change the button I clicked to the specified colour. Right now my code is resetting it back to default and not showing the clicked button colour.

 document.querySelectorAll(".difficulty-button").forEach((gameMode) => { gameMode.addEventListener("click", function() { let linkColour = window.getComputedStyle(gameMode); document.querySelectorAll(".difficulty-button").forEach((item) => { item.style.backgroundColor = "green"; item.style.color = "black"; }); gameMode.style.backgroundColor = linkColour.backgroundColor; }); });
 ul { display: flex; justify-content: center; } ul li { padding: 0; list-style: none; } button { box-shadow: none; outline: none; width: 10em; height: 3.5em; transition: 0.25s linear; cursor: pointer; background-color: white; } li:nth-child(1) button:hover { background-color: rgb(51, 165, 50); color: white; } li:nth-child(2) button:hover { background-color: rgb(255, 255, 0); } li:nth-child(3) button:hover { background-color: rgb(204, 50, 50); color: white; } li:nth-child(4) button:hover { background-color: black; color: white; }
 <ul> <li><button class="difficulty-button">Easy</button></li> <li><button class="difficulty-button">Medium</button></li> <li><button class="difficulty-button">Hard</button></li> <li><button class="difficulty-button">Insane</button></li> </ul>

The reason this only works the first time is to do with the way you get the colour to apply to the button, and how you apply the new colour.

Why it doesn't work:

You are using getComputedStyle to get the colour of the button when it is clicked. The first time it's clicked the hover class is applied, so to use is the one you clicked.

However then the javascript changes all the buttons to green directly using inline styles. These will override any other CSS being applied. Now every time you click, all the buttons are set to green so that colour is getting applied again.

Getting it to work: How to Swap CSS Classes on Click

You could hardcode the colours into the JS function and have an if to check which button it is. But a more flexible way to do this is to use your classes again.

1. Set up your CSS Classes . We already have rules set up for the colours you want, so if we give then a class name we can use them in the js, eg

.colorbutton-1,   /* give the existing 1st button CSS a class called "colorbutton-1" */
li:nth-child(1) button:hover{
    background-color: rgb(51, 165, 50);
    color: white;
}

Do this for each button, and also set one up for the default unselected state, eg

.colorbutton-0{
    background-color:green;
    color: black;
}

Note the classes all start with the same name colorbutton - this is important! This is what we will use in the js later.

2. Write a function to swap the classes on the buttons depending on what was clicked. We'll pass in the button and which button number this is (ie 1,2,3,4).

In the function we remove all classes starting with colorbutton , and then add the new class - this is made up of the colorbutton- and the number of the button. If we want to apply the unselected style, we use 0.

function swapClass(btnElement, btnNum){
    // remove all existing classes  starting with "colorbutton"
    btnElement.classList.forEach(className => {
        if (className.startsWith('colorbutton')) 
            btnElement.classList.remove(className);
    });
     // now add the new class
    btnElement.classList.add('colorbutton-'+ btnNum);
}

3. Add your click listeners to listen for clicks and change the classes depending on which button was clicked.

// add a "counter" in forEach that passes the index of the element being processed, e.g. 0,1,2 etc
document.querySelectorAll(".difficulty-button").forEach((gameMode, btnNum) => {
    // add the click listener for the current button
    gameMode.addEventListener("click", function () {
        // on a click, remove all 'colorbutton' classes and set them to the default
        document.querySelectorAll(".difficulty-button").forEach((item) => {
            swapClass(item, 0);
        });
        // add the class for this button, passing in the class number to generate the classname
        swapClass(this, (btnNum+1));
    });
});

Working Example Putting this all together:

 document.querySelectorAll(".difficulty-button").forEach((gameMode, btnNum) => { gameMode.addEventListener("click", function () { document.querySelectorAll(".difficulty-button").forEach((item) => { changeClass(item, 0); }); changeClass(this, (btnNum+1)); }); }); function changeClass(btnElement, classRef){ // remove all existing classes starting with "colorbutton" btnElement.classList.forEach(className => { if (className.startsWith('colorbutton')) btnElement.classList.remove(className); }); // now add the new class btnElement.classList.add('colorbutton-'+classRef); }
 ul { display: flex; justify-content: center; } ul li { padding: 0; list-style: none; } button { box-shadow: none; outline: none; width: 10em; height: 3.5em; transition: 0.25s linear; cursor: pointer; background-color: white; } .colorbutton-0{ background-color:green; color: black; } .colorbutton-1, li:nth-child(1) button:hover{ background-color: rgb(51, 165, 50); color: white; } .colorbutton-2, li:nth-child(2) button:hover{ background-color: rgb(255, 255, 0); } .colorbutton-3, li:nth-child(3) button:hover{ background-color: rgb(204,50,50); color: white; } .colorbutton-4, li:nth-child(4) button:hover{ background-color: black; color: white; }
 <ul> <li><button class="difficulty-button">Easy</button></li> <li><button class="difficulty-button">Medium</button></li> <li><button class="difficulty-button">Hard</button></li> <li><button class="difficulty-button">Insane</button></li> </ul>

Just like the pseudo class you are using for button:hover , CSS also provides pseudo classes for active and visited . You should be able to do something like the following, which would change the color of the button once it is selected and revert it when new button is selected.

li:nth-child(4) button:active {
    background-color: black;
    color: white;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM