简体   繁体   中英

Javascript 'click' button only works once than have to refresh page

so Im working on this interactive Grid and have it set up so when I clicked a button the grids divs change background color according to the button chosen. My issue is that I can only click each button once and after that it will not work until I refresh the page. how do I fix this so can change the colors as many time as I want?

HTML

<!DOCTYPE html>
<html>
    <head> 
         <title> Claudias Etch-A-Sketch</title>
         <link rel= "stylesheet"  href="style.css">     
    </head>


<body>
   <section class="back"> 
       <h1><center> Claudia Etch-A-Sketch!</center></h1>
    </section>

   <section>
        <div>      
            <button class="Black">Black</button>
            <button class="Random">Random Color</button>
            <button class="Clear">Clear Board</button>
        </div>
    </section>
<section>

 <div id = "container"> </div>

</section>
</body>

<script src ="javascript.js"> </script>
</html>

JAVASCRIPT

const container = document.getElementById("container");
const btn= document.querySelector('button');


let y = document.querySelectorAll('button');
y.forEach(button => {
    button.addEventListener('click', () => {
        let choice = button.innerHTML;
        switch (choice) {
            case "Random Color":
                random();
                break;
            case "Black":
                blackchange();
                break;
            case "Clear Board":
                reset();
                break;
        }
    });
})


function blackchange() { const bb = container.addEventListener('mouseover', e=> e.target.classList.add('black'))};


function random() {
  const rr= container.addEventListener('mouseover', e=> e.target.classList.add('random'))
};

function reset () { const rr= container.addEventListener('mouseover', e => e.target.classList.add('reset'))};

function makeRows(rows, cols) {
  container.style.setProperty('--grid-rows', rows);
  container.style.setProperty('--grid-cols', cols);
  for (c = 0; c < (rows * cols); c++) {
    let cell = document.createElement("div")


   container.appendChild(cell).className = "griditem"

  }; 
};

makeRows(16, 16);

Your main problem is that you keep adding mouseover event listeners on the container, and your cells end up having both random and black classes. Then, trying to add one or the other won't change anything. You need to remove the other color's class and apply only the one you want.

You could also make your life easier by only adding the mouseover event listener once, and use a variable for the color, which this event handler will use.

Try the demo below:

 const container = document.getElementById("container"); const buttons = document.querySelectorAll('button'); let cells = []; let selectedColor = null; buttons.forEach(button => { button.addEventListener('click', () => { switch (button.id) { case "black-btn": selectColor('black'); break; case "random-btn": selectColor('random'); break; case "clear-btn": reset(); break; } }); }) container.addEventListener('mouseover', e => { if (selectedColor !== null) { e.target.classList.remove('black', 'random'); e.target.classList.add(selectedColor); } }); function reset() { cells.forEach(cell => cell.classList.remove('black', 'random')); } function selectColor(color) { selectedColor = color; buttons.forEach(button => { button.classList[button.id === `${color}-btn` ? 'add' : 'remove']('active'); }); } function makeRows(rows, cols) { container.style.setProperty('--grid-rows', rows); container.style.setProperty('--grid-cols', cols); for (c = 0; c < (rows * cols); c++) { let cell = document.createElement("div"); cells.push(cell); container.appendChild(cell).className = "griditem"; }; }; makeRows(16, 16);
 body { font-family: Arial, Helvetica, sans-serif; } h1 { font-size: 16px; } button.active { box-shadow: 0 0 3px #882ac6; } #container { background: #eee; display: grid; height: 150px; width: 150px; grid-template-columns: repeat(16, 1fr); } .griditem.black { background: black; } .griditem.random { -webkit-animation: random 3s infinite; animation: random 3s infinite; } @keyframes random { 0% { background-color: purple; } 15% { background-color: red; } 30% { background-color: yellow; } 45% { background-color: green; } 60% { background-color: blue; } 75% { background-color: orange; } 100% { background-color: purple; } }
 <h1>Claudia Etch-A-Sketch!</h1> <div> <button id="black-btn">Black</button> <button id="random-btn">Random Color</button> <button id="clear-btn">Clear Board</button> </div> <div id="container"></div>

You are forgetting that everything you're doing to the page has to be cleaned up, or the effects of what you've done will still linger.

When you set a new mouseover function, you need to remove the old mouseover function first with removeEventListener . You're also going to want to remove other classes the user may have added to elements in the past with a mouseover before adding the new class.

Try this out:

 const container = document.getElementById("container"); const btn = document.querySelector('button'); let y = document.querySelectorAll('button'); y.forEach(button => { button.addEventListener('click', () => { let choice = button.innerHTML; switch (choice) { case "Random Color": random(); break; case "Black": blackchange(); break; case "Eraser": reset(); break; } }); }); var currentMouseoverFunction = function() {}; function blackchange() { container.removeEventListener('mouseover', currentMouseoverFunction); currentMouseoverFunction = function(e) { e.target.classList.remove('random'); e.target.classList.remove('reset'); e.target.classList.add('black'); }; container.addEventListener('mouseover', currentMouseoverFunction); }; function random() { container.removeEventListener('mouseover', currentMouseoverFunction); currentMouseoverFunction = function(e) { e.target.classList.remove('black'); e.target.classList.remove('reset'); e.target.classList.add('random'); }; container.addEventListener('mouseover', currentMouseoverFunction); }; function reset() { container.removeEventListener('mouseover', currentMouseoverFunction); currentMouseoverFunction = function(e) { e.target.classList.remove('black'); e.target.classList.remove('random'); e.target.classList.add('reset'); }; container.addEventListener('mouseover', currentMouseoverFunction); }; function makeRows(rows, cols) { container.style.setProperty('--grid-rows', rows); container.style.setProperty('--grid-cols', cols); for (c = 0; c < (rows * cols); c++) { let cell = document.createElement("div"); container.appendChild(cell).className = "griditem"; }; }; makeRows(16, 16);
 #container{ width:160px; height:160px; margin-top:10px; background:#eee; } #container div { float:left; height: 10px; width: 10px; } .black { background: black; } .random { background: pink; } .reset { background: transparent; }
 <section class="back"> <h1> <center> Claudia Etch-A-Sketch!</center> </h1> </section> <section> <div> <button class="Black">Black</button> <button class="Random">Random Color</button> <button class="Clear">Eraser</button> </div> </section> <section> <div id="container"> </div> </section>

I added my own simple CSS for testing purposes because I didn't have access to yours.

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