简体   繁体   中英

How to access and change multiple classes with the same name and loop through them to add a css change to them upon click?

I am a beginner. So I am making a drum pad with 6 interactive pads using javascript. I want to be able to change the color of each pad upon clicking/touching it. The way my code works now, only the first (top left) pad gets changed by the click. I would like to have this effect happen to all the pads. querySelectorAll() on the pad variable doesn't seem to do the trick. It actually stops the first pad from being activated at all. Any tips? Thanks!

 const drumKit = document.querySelector('.drumkit'); let pad = document.querySelector('.pad'); function playDrum(event) { if (event.target.classList.contains('pad')) { event.preventDefault(); let soundToPlay = event.target.dataset.sound; drums.play(soundToPlay); pad.classList.add('playing'); } } function setViewportHeight() { let vh = window.innerHeight * 0.01; document.documentElement.style.setProperty('--vh', `${vh}px`); } setViewportHeight(); window.addEventListener('resize', setViewportHeight); drumKit.addEventListener('click', playDrum); drumKit.addEventListener('touchstart', playDrum);
 body { background: #353535 }.drumkit { display: flex; flex-wrap: wrap; justify-content: center; height: 100vh; height: calc(var(--vh, 1vh) * 100); }.pad { display: flex; justify-content: center; align-items: center; margin: 10px; box-shadow: 0 0 10px #000000; flex: 1 0 calc(33.333% - 20px); background: radial-gradient(#e3a864, #de9866, #d08367, #af6762); }.playing { transform: scale(-1.-1); border-color: #ffc600; box-shadow: 0 0 1rem #ffc600; }.pad img { width: 150px; pointer-events: none; }
 <,DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width. initial-scale=1.0"> <link rel="shortcut icon" href="#"> <link rel="stylesheet" href="./styles.css"> <title>Lofi Beat Machine</title> </head> <body> <div class="drumkit"> <div class="pad" data-sound="samp1"><img src="./icons/sample.png" alt="samp1"></div> <div class="pad" data-sound="samp2"><img src="./icons/sample.png" alt="samp2"></div> <div class="pad" data-sound="samp3"><img src="./icons/sample.png" alt="samp3"></div> <div class="pad" data-sound="kick"><img src="./icons/kick.png" alt="kick"></div> <div class="pad" data-sound="snare"><img src="./icons/snare.png" alt="snare"></div> <div class="pad" data-sound="hat"><img src="./icons/closed-hihat.png" alt="hihat"></div> </div> <script src="howler.min.js"></script> <script src="app.js"></script> </body> </html>

Nice job so far on the project! You were right in using querySelectorAll , but you'll need to loop through the elements to add the onClick to all the pads. First I'd change the pad variable to querySelectorAll like this:

  let pad = document.querySelectorAll('.pad');

And since pad is now an array, we'll change the playDrum function by updating pad.classList.add() to event.target.classList.add() like this:

  event.target.classList.add('playing');       

event.target will target the specific pad you have clicked. Lastly, when attaching your onClick event, you can use a forEach function like this:

  pad.forEach(elem => elem.addEventListener("click", playDrum));

And you can remove the drumKit.addEventListener('touchstart', playDrum); , it's not needed when the onClick function is attached to all the individual pads.

Here's the JS with all the changes:

const drumKit = document.querySelector('.drumkit');
let pad = document.querySelectorAll('.pad');

function playDrum(event) {
    if (event.target.classList.contains('pad')) {
        event.preventDefault();
        let soundToPlay = event.target.dataset.sound;
        drums.play(soundToPlay);

        event.target.classList.add('playing');       
    }
}
function setViewportHeight() {
    let vh = window.innerHeight * 0.01;
    document.documentElement.style.setProperty('--vh', `${vh}px`);
}

setViewportHeight();

window.addEventListener('resize' , setViewportHeight);

pad.forEach(elem => elem.addEventListener("click", playDrum));

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