My drum machine works correctly when I press the keyboard keys (Q,W,E,A,S,D,Z,X,C) sound plays and #display updates. But clicking the pads with the mouse does nothing: no sound, no console output, no errors.
I tested with a console.log inside the click handler and it never fires. My keydown handler using the same triggerPad() function works fine.
HTML, CSS and JS all pass FCC’s own logic checks and match the standard working solution structure. Anyone seen this specific click-not-firing issue on the new lab-drum-machine platform (freecodecamp.org/learn/javascript-v9/lab-drum-machine )?
Here is my codes:
HTML:
<div id="drum-machine">
<div id="pad-bank">
<button class="drum-pad" id="heater1" type="button">
Q
<audio class="clip" id="Q" src="https://cdn.freecodecamp.org/curriculum/drum/Heater-1.mp3"></audio>
</button>
<button class="drum-pad" id="heater2" type="button">
W
<audio class="clip" id="W" src="https://cdn.freecodecamp.org/curriculum/drum/Heater-2.mp3"></audio>
</button>
<button class="drum-pad" id="heater3" type="button">
E
<audio class="clip" id="E" src="https://cdn.freecodecamp.org/curriculum/drum/Heater-3.mp3"></audio>
</button>
<button class="drum-pad" id="heater4" type="button">
A
<audio class="clip" id="A" src="https://cdn.freecodecamp.org/curriculum/drum/Heater-4_1.mp3"></audio>
</button>
<button class="drum-pad" id="clap" type="button">
S
<audio class="clip" id="S" src="https://cdn.freecodecamp.org/curriculum/drum/Heater-6.mp3"></audio>
</button>
<button class="drum-pad" id="openhh" type="button">
D
<audio class="clip" id="D" src="https://cdn.freecodecamp.org/curriculum/drum/Dsc_Oh.mp3"></audio>
</button>
<button class="drum-pad" id="kicknhat" type="button">
Z
<audio class="clip" id="Z" src="https://cdn.freecodecamp.org/curriculum/drum/Kick_n_Hat.mp3"></audio>
</button>
<button class="drum-pad" id="kick" type="button">
X
<audio class="clip" id="X" src="https://cdn.freecodecamp.org/curriculum/drum/RP4_KICK_1.mp3"></audio>
</button>
<button class="drum-pad" id="closedhh" type="button">
C
<audio class="clip" id="C" src="https://cdn.freecodecamp.org/curriculum/drum/Cev_H2.mp3"></audio>
</button>
</div>
<p id="display">Ready</p>
</div>
CSS;
#drum-machine {
text-align: center;
}
#pad-bank {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
max-width: 420px;
margin: 0 auto;
}
.drum-pad {
cursor: pointer;
padding: 18px;
font-size: 18px;
}
JAVA
const drumPads = document.querySelectorAll('.drum-pad');
const display = document.getElementById('display');
function handleTrigger(element) {
const audio = element.querySelector('.clip');
if (audio) {
audio.currentTime = 0;
audio.play();
display.innerText = element.id.replace(/-/g, ' ');
}
}
drumPads.forEach((pad) => {
pad.addEventListener('click', () => {
handleTrigger(pad);
});
});
document.addEventListener('keydown', (e) => {
const key = e.key.toUpperCase();
const audio = document.getElementById(key);
if (audio) {
handleTrigger(audio.parentElement);
}
});
Teller
July 10, 2026, 11:44pm
2
Welcome to the forum @Havana72
Mouse clicks and keys are separate events.
Happy coding
Ray13
July 11, 2026, 5:34pm
3
There are two ways you can format your code to make it easier to read and test:
After you copy/paste your code into the editor, select it by dragging your cursor over it then click the (</>) button in the toolbar to automatically wrap your code in backticks. (You can click on the animated demo image below to enlarge it.)
Manually add three backticks on a new line above your code and on a new line after your code. Note that a backtick is NOT the same as a single quote('). To find the backtick key on your keyboard, see this post .
To see changes to your post as you make them, you can click the (M+) button on the toolbar to bring up the rich text editor:
HTML:
<div id="drum-machine">
<div id="pad-bank">
<button class="drum-pad" id="heater1" type="button">Q<audio class="clip" id="Q" src="Heater-1.mp3"></audio></button>
<button class="drum-pad" id="heater2" type="button">W<audio class="clip" id="W" src="Heater-2.mp3"></audio></button>
<button class="drum-pad" id="heater3" type="button">E<audio class="clip" id="E" src="Heater-3.mp3"></audio></button>
<button class="drum-pad" id="heater4" type="button">A<audio class="clip" id="A" src="Heater-4_1.mp3"></audio></button>
<button class="drum-pad" id="clap" type="button">S<audio class="clip" id="S" src="Heater-6.mp3"></audio></button>
<button class="drum-pad" id="openhh" type="button">D<audio class="clip" id="D" src="Dsc_Oh.mp3"></audio></button>
<button class="drum-pad" id="kicknhat" type="button">Z<audio class="clip" id="Z" src="Kick_n_Hat.mp3"></audio></button>
<button class="drum-pad" id="kick" type="button">X<audio class="clip" id="X" src="RP4_KICK_1.mp3"></audio></button>
<button class="drum-pad" id="closedhh" type="button">C<audio class="clip" id="C" src="Cev_H2.mp3"></audio></button>
</div>
<p id="display">Ready</p>
</div>
CSS:
#drum-machine { text-align: center; }
#pad-bank { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; max-width: 420px; margin: 0 auto; }
.drum-pad { cursor: pointer; padding: 18px; font-size: 18px; }
JavaScript:
const drumPads = document.querySelectorAll('.drum-pad');
const display = document.getElementById('display');
function handleTrigger(element) {
const audio = element.querySelector('.clip');
if (audio) {
audio.currentTime = 0;
audio.play();
display.innerText = element.id.replace(/-/g, ' ');
}
}
drumPads.forEach((pad) => {
pad.addEventListener('click', () => {
handleTrigger(pad);
});
});
document.addEventListener('keydown', (e) => {
const key = e.key.toUpperCase();
const audio = document.getElementById(key);
if (audio) {
handleTrigger(audio.parentElement);
}
});
Can you tell us about the code you’ve posted?
There are two ways you can format your code to make it easier to read and test:
After you copy/paste your code into the editor, select it by dragging your cursor over it then click the (</>) button in the toolbar to automatically wrap your code in backticks. (You can click on the animated demo image below to enlarge it.)
Manually add three backticks on a new line above your code and on a new line after your code. Note that a backtick is NOT the same as a single quote('). To find the backtick key on your keyboard, see this post .
To see changes to your post as you make them, you can click the (M+) button on the toolbar to bring up the rich text editor:
Hey, thanks for asking! So the project is a Drum Machine build for the FreeCodeCamp certification. The core layout and functionality are done, but I’m stuck on a bug: the audio isn’t triggering correctly I suspect it’s an issue with how the audio elements are sandboxed/loaded (possibly an iframe or autoplay restriction issue) rather than the click-handling logic itself, since the UI responds fine but no sound plays. I’ve gone through the logic step by step and it looks correct on paper, so I think it’s an environment/loading issue rather than a JS logic bug. Still debugging it if you’ve run into something similar, I’d love any pointers.
<div id="drum-machine">
<div id="pad-bank">
<button class="drum-pad" id="heater1" type="button">
Q
<audio class="clip" id="Q" src="https://cdn.freecodecamp.org/curriculum/drum/Heater-1.mp3"></audio>
</button>
<button class="drum-pad" id="heater2" type="button">
W
<audio class="clip" id="W" src="https://cdn.freecodecamp.org/curriculum/drum/Heater-2.mp3"></audio>
</button>
<button class="drum-pad" id="heater3" type="button">
E
<audio class="clip" id="E" src="https://cdn.freecodecamp.org/curriculum/drum/Heater-3.mp3"></audio>
</button>
<button class="drum-pad" id="heater4" type="button">
A
<audio class="clip" id="A" src="https://cdn.freecodecamp.org/curriculum/drum/Heater-4_1.mp3"></audio>
</button>
<button class="drum-pad" id="clap" type="button">
S
<audio class="clip" id="S" src="https://cdn.freecodecamp.org/curriculum/drum/Heater-6.mp3"></audio>
</button>
<button class="drum-pad" id="openhh" type="button">
D
<audio class="clip" id="D" src="https://cdn.freecodecamp.org/curriculum/drum/Dsc_Oh.mp3"></audio>
</button>
<button class="drum-pad" id="kicknhat" type="button">
Z
<audio class="clip" id="Z" src="https://cdn.freecodecamp.org/curriculum/drum/Kick_n_Hat.mp3"></audio>
</button>
<button class="drum-pad" id="kick" type="button">
X
<audio class="clip" id="X" src="https://cdn.freecodecamp.org/curriculum/drum/RP4_KICK_1.mp3"></audio>
</button>
<button class="drum-pad" id="closedhh" type="button">
C
<audio class="clip" id="C" src="https://cdn.freecodecamp.org/curriculum/drum/Cev_H2.mp3"></audio>
</button>
</div>
<p id="display">Ready</p>
</div>
#drum-machine {
text-align: center;
}
#pad-bank {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
max-width: 420px;
margin: 0 auto;
}
.drum-pad {
cursor: pointer;
padding: 18px;
font-size: 18px;
}
function init() {
const pads = document.querySelectorAll(".drum-pad");
const display = document.getElementById("display");
const labels = {
Q: "Heater 1",
W: "Heater 2",
E: "Heater 3",
A: "Heater 4",
S: "Clap",
D: "Open-HH",
Z: "Kick-n'-Hat",
X: "Kick",
C: "Closed-HH",
};
function triggerPad(pad) {
const audio = pad.querySelector("audio.clip");
if (!audio) return;
display.textContent = labels\[audio.id\] || audio.id;
try {
audio.currentTime = 0;
audio.play();
} catch (err) {
// ignore playback errors so the display still updates
}
}
pads.forEach((pad) => {
pad.addEventListener("click", () => triggerPad(pad));
});
document.addEventListener("keydown", (event) => {
const key = event.key.toUpperCase();
const audio = document.getElementById(key);
if (audio && audio.classList.contains("clip")) {
const pad = audio.closest(".drum-pad");
if (pad) triggerPad(pad);
}
});
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
init();
}
dhess
July 15, 2026, 4:15pm
9
I’ve edited your code for readability and testability. In the future, please review the above posts to correctly format your code for the forum.
Thank you.
dhess
July 15, 2026, 4:17pm
10
Hi @Havana72 ,
Please provide a link to this challenge.
The HTML you posted is incomplete. We can’t test with incomplete code. Please refer to this HTML Boilerplate theory lecture for the basic structure of an HTML webpage.
Happy coding
Did you investigate this feedback or make any changes related to it?
```
```
```
#drum-machine {
text-align: center;
}
#pad-bank {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
max-width: 420px;
margin: 0 auto;
}
.drum-pad {
cursor: pointer;
padding: 18px;
font-size: 18px;
}
```
```
function init() {
const pads = document.querySelectorAll(“.drum-pad”);
const display = document.getElementById(“display”);
const labels = {
Q: “Heater 1”,
W: “Heater 2”,
E: “Heater 3”,
A: “Heater 4”,
S: “Clap”,
D: “Open-HH”,
Z: “Kick-n’-Hat”,
X: “Kick”,
C: “Closed-HH”,
};
function triggerPad(pad) {
const audio = pad.querySelector(“audio.clip”);
if (!audio) return;
audio.currentTime = 0;
audio.play();
display.textContent = labels[audio.id] || audio.id;
}
pads.forEach((pad) => {
pad.addEventListener(“click”, () => triggerPad(pad));
});
document.addEventListener(“keydown”, (event) => {
const key = event.key.toUpperCase();
const audio = document.getElementById(key);
if (audio && audio.classList.contains(“clip”)) {
const pad = audio.closest(“.drum-pad”);
if (pad) triggerPad(pad);
}
});
}
if (document.readyState === “loading”) {
document.addEventListener(“DOMContentLoaded”, init);
} else {
init();
}
```
<button class="drum-pad" id="heater1" type="button">
Q
<audio class="clip" id="Q" src="https://cdn.freecodecamp.org/curriculum/drum/Heater-1.mp3"></audio>
</button>
<button class="drum-pad" id="heater2" type="button">
W
<audio class="clip" id="W" src="https://cdn.freecodecamp.org/curriculum/drum/Heater-2.mp3"></audio>
</button>
<button class="drum-pad" id="heater3" type="button">
E
<audio class="clip" id="E" src="https://cdn.freecodecamp.org/curriculum/drum/Heater-3.mp3"></audio>
</button>
<button class="drum-pad" id="heater4" type="button">
A
<audio class="clip" id="A" src="https://cdn.freecodecamp.org/curriculum/drum/Heater-4_1.mp3"></audio>
</button>
<button class="drum-pad" id="clap" type="button">
S
<audio class="clip" id="S" src="https://cdn.freecodecamp.org/curriculum/drum/Heater-6.mp3"></audio>
</button>
<button class="drum-pad" id="openhh" type="button">
D
<audio class="clip" id="D" src="https://cdn.freecodecamp.org/curriculum/drum/Dsc_Oh.mp3"></audio>
</button>
<button class="drum-pad" id="kicknhat" type="button">
Z
<audio class="clip" id="Z" src="https://cdn.freecodecamp.org/curriculum/drum/Kick_n_Hat.mp3"></audio>
</button>
<button class="drum-pad" id="kick" type="button">
X
<audio class="clip" id="X" src="https://cdn.freecodecamp.org/curriculum/drum/RP4_KICK_1.mp3"></audio>
</button>
<button class="drum-pad" id="closedhh" type="button">
C
<audio class="clip" id="C" src="https://cdn.freecodecamp.org/curriculum/drum/Cev_H2.mp3"></audio>
</button>
Ready
```
```
#drum-machine {
text-align: center;
}
#pad-bank {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
max-width: 420px;
margin: 0 auto;
}
.drum-pad {
cursor: pointer;
padding: 18px;
font-size: 18px;
}
```
```
function init() {
const pads = document.querySelectorAll(“.drum-pad”);
const display = document.getElementById(“display”);
const labels = {
Q: "Heater 1",
W: "Heater 2",
E: "Heater 3",
A: "Heater 4",
S: "Clap",
D: "Open-HH",
Z: "Kick-n'-Hat",
X: "Kick",
C: "Closed-HH",
};
function triggerPad(pad) {
const audio = pad.querySelector("audio.clip");
if (!audio) return;
audio.currentTime = 0;
audio.play();
display.textContent = labels\[audio.id\] || audio.id;
}
pads.forEach((pad) => {
pad.addEventListener("click", () => triggerPad(pad));
});
document.addEventListener(“keydown”, (event) => {
const key = event.key.toUpperCase();
const audio = document.getElementById(key);
if (audio && audio.classList.contains("clip")) {
const pad = audio.closest(".drum-pad");
if (pad) triggerPad(pad);
}
});
}
if (document.readyState === “loading”) {
document.addEventListener(“DOMContentLoaded”, init);
} else {
init();
}
```
Hey, I’m having trouble getting the full code to post correctly. I followed the backtick instructions exactly, but when I paste it in, the index.html gets cut off halfway through every time — I’m not sure why. I’ve been stuck on this specific bug for about ten days now and could really use some help.
Is there another way I could share the code with you — like a CodePen link, GitHub Gist, or the direct freeCodeCamp challenge link — that might work better than pasting it directly here?
dhess
July 15, 2026, 9:45pm
17
Using the backtick method, are you entering three backticks (```) on a line, then pasting your code in after that line? Maybe try a small test here to see how it works.
And don’t forget this tip so you can see how your code looks before you post it:
dhess
July 15, 2026, 9:58pm
18
And I have to ask…why are you posting your code again? Your HTML is still incomplete.
What are your failed tests when you click the “Check Your Code” button?
Yes, I’ve done exactly that three backticks, Enter, paste, Enter, three backticks again. I even confirmed it visually before posting. The problem is that when I paste, my index.html gets cut off partway through, not that I’m missing the backtick formatting.”
Also, would it be possible to share this some other way like a CodePen or GitHub Gist link since pasting directly here keeps cutting off? I’ve been stuck on this exact bug for about eight days and just want to get it resolved
Yes you can share it that way
dhess
July 15, 2026, 10:36pm
21
What are your failed tests when you click the “Check Your Code” button?
This is important information that will help us help you.
This is the problem with formatting your code. You do not want the escape backslashes.