Why doesn't my javascript keydown event change the color of my innerHTML?

I have developed a website featuring multiple buttons that can be clicked using the mouse or activated with corresponding keyboard letters. When a user presses the assigned letter on the keyboard, the button should play a unique sound and change its text color to orange. Everything is functioning correctly except for one issue - when a button is activated via keyboard input, the text color does not change on-screen. Can you help me identify what's causing this problem in my code?

Below is the JavaScript code snippet used in my project:

// Button click detection
for (var i = 0; i <= 6; i++) {
  document.querySelectorAll("button")[i].addEventListener("click", function() {
      var buttonInnerHTML = this.innerHTML;
      this.style.color = "orange";
        makeSound(buttonInnerHTML);
    }
  );
}


// Keyboard keydown detection works but doesn't change color
document.addEventListener("keydown", function(event) {
  var button = event.target;
  var buttonInnerHTML = button.innerHTML;
  button.style.color = "orange";
  makeSound(event.key);
})


// Sound generation function
function makeSound(key) {

  switch (key) {
    case "w":
      var tom1 = new Audio("sounds/tom-1.mp3");
      tom1.play();
      break;

    // Additional cases for other keys...

    default:
      console.log(buttonInnerHTML);
  }
}

And here is a snippet of the HTML body related to these buttons:

<body>

  <h1 id="title">Drum 🥁 Kit</h1>
  <div class="set">
    <button class="w drum">w</button>
    <button class="a drum">a</button>
    <button class="s drum">s</button>
    <button class="d drum">d</button>
    <button class="j drum">j</button>
    <button class="k drum">k</button>
    <button class="l drum">l</button>
  </div>

<script src="index2.js" charset="utf-8"></script>

  <footer>

  </footer>
</body>

Answer №1

You have set up a keypress event listener on the document using

document.addEventListener("keydown", function(event) {...}
. However, within that function, you are trying to target the button using event.target, which may not work as expected. Since the keypress event is applied globally to the document, how will it know which button to highlight when a key is pressed?

A solution could be to extract the key pressed from the event and use it to select the corresponding button using a class selector...

document.addEventListener("keydown", function(event) {
  var button = document.getElementsByClassName(String.fromCharCode(event.which).toLowerCase())[0];
  var buttonInnerHTML = button.innerHTML;
  button.style.color = "orange";
  makeSound(event.key);
})

In this modified code snippet, I replaced event.target with

document.getElementsByClassName(String.fromCharCode(event.which).toLowerCase())[0];
.

Since you have already defined the class in the element you want to modify, it should work seamlessly out of the box...

<button class="w drum">w</button>

Check out the full working demo online.

Answer №2

When you apply the orange text styling to the document, it affects the entire document rather than just individual buttons when a letter is pressed because event.target returns the element the event was applied to.

To target specific buttons, you may need to change the line button.style.color = "orange"; to something like

document.getElementsByClassName("w drum")[0].style.color = "orange";
and place it under the relevant case such as case "w":

Answer №3

To improve your code, consider attaching the keydown event to individual buttons instead of the entire document. This approach is similar to how you handle the click event.

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

AngularJS: Identifying the position (ON/OFF) of ui-switch

I'm having trouble figuring out how to identify the position of my UI switch (true/false) in my JavaScript file. Here is my HTML file with the UI switch: <ui-switch ng-model='onOff'></ui-switch> And here is my controller for t ...

Displaying duration of time through JQuery along with present day and time

I'm working on a web application where I display the date and time of a posted request in the user interface. Now, I want to enhance this by showing how long ago that request was posted relative to the current Date and time. Is there a simple way to ...

Using Mocha in Node to make XMLHttprequests

Currently, I am experimenting with using node-xmlhttprequest. Here is an example of what I have been working on: // f.js (function() XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest xhr = new XMLHttpRequest() xhr.open('GET ...

Executing a DELETE request through a hyperlink in a Node.js Express application

I'm working with a route that accepts DELETE requests, and I am aware that in Express you can include <input type="hidden" name="_method" value="delete" /> in a form to send a POST request to the designated URL. But how would you accomplish ...

Tips for refreshing an angularjs $scope using $.get jquery

Attempting to implement the code below using $scope: var scopes = "https://www.googleapis.com/auth/contacts.readonly"; setTimeout(authorize(), 20); function authorize() { gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: false}, h ...

Incorporate an Ajax request onto an existing link within a div element

Here is what I have: <div id="div-for-ajax-onclick"> <a href="http://www.google.com">Link to google</a> </div> $("#div-for-ajax-onclick").click(function() { // update database }); I am looking for a solution where if someone c ...

The success function is not functioning properly with the validation engine

I'm having trouble getting this script to function properly as it keeps showing errors whenever I try to run it. $(document).ready(function() { $("#form1").validationEngine({ ajaxSubmit: true, ajaxSubmitFile: "note/note.php", ...

Effective model synchronization in Angular UI when filtering applied between two lists

Currently, I am utilizing Sortable in AngularUI to handle multiple sortable lists. I have successfully set it up so that I can easily move items between the lists and update the respective models accordingly. However, when adding a query filter, I encounte ...

What is the best way to add an array of JSON objects to another array of JSON objects?

The current JSON array obtained from the response is as follows: comments:[{id: "3124fac5-9d3e-4fa9-8a80-10f626fbf141", createdDate: 1469606019000,…},…] 0:{id: "3124fac5-9d3e-4fa9-8a80-10f626fbf141", createdDate: 1469606019000,…} createdBy:{id: "cf2 ...

Implement a FOR loop in conjunction with an AJAX request

My goal is to send an AJAX request with multiple form fields and use an array for validations. I would like to also pass these values via AJAX: Although I haven't used a for loop in JavaScript before, it looks familiar. The current approach of the l ...

Wait for the completion of a Promise inside a for-loop in Javascript before returning the response

After completing a Promise within a for-loop, I am attempting to formulate a response. Although I have reviewed these questions, my scenario remains unaddressed. The methodGetOrders and methodGetLines are components of an external library that must be ut ...

Is there a way for me to retrieve the current value of a star rating when I click on it?

Looking for assistance with a ReactJS rating stars component that behaves oddly. The starting value is set to 5 stars, but each click on the stars seems to return the previous value rather than the current one. import React, {useState} from "react&quo ...

Sinon - using callbacks in stubbed functions leading to test method exceeding time limit

One of my express route methods is structured as follows: exports.register_post = function(req, res) { var account = new Account(); account.firstName = req.param('firstName'); //etc... account.save(function(err, result) { ...

Tips for conducting unit tests on navigator.notification.alert

I am currently facing a challenge in writing a unit test for a JavaScript function where I need to fake the navigator.notification.alert method. Can anyone provide suggestions or solutions? Below is the code snippet that I have attempted: navigator = { ...

Why are XAxis categories appearing as undefined in tooltip when clicked?

[When clicking on the x-axis, the values go from 0 to 1. I need the x-axis categories values to display on click event. When hovering over the x-axis value, it shows properly, but clicking on the x-axis does not show the correct values] Check out this fid ...

Angular model is not receiving the value of a false checkbox

One issue I am facing is with a form that includes a checkbox bound to an ng-model property. The problem arises when the checkbox is checked, as the value gets set in the model. However, when it is unchecked, the key and value remain unset, causing API val ...

Developing HTML5 animation by utilizing sprite sheets

Struggling to create an engaging canvas animation with the image provided in the link below. Please take a look at https://i.stack.imgur.com/Pv2sI.jpg I'm attempting to run this sprite sheet image for a normal animation, but unfortunately, I seem to ...

I've been diving into webpack and experimenting with making an api call, but I'm hitting a roadblock. Let me share with you my code

This section pertains to the server const dotenv = require('dotenv'); dotenv.config(); // Setting up environment variables const express = require('express'); const bodyParser = require('body-parser'); const cors = require(&a ...

Exploring hierarchical information within a JSON response from a Wiki API

As a newcomer to this field, I am currently exploring ways to access Wikipedia's API for extracting the value of "extract" and adding it to an HTML element dynamically. The challenge lies in the fact that the information is subject to change based on ...

Persistent Error from Express Custom Validator

In my login API, there is a function called ifIDAlreadyExist that checks the database to validate new user details. It returns true or false depending on whether the ID exists or not. However, even when the result is false, an error message is still retur ...