Small Js file acting eractically. No idea why

I’d appreciate it if someone can aid me with an issue, I cannot see any clues as to why the js file is not acting as expected. I have asked ai, searched, and cannot see what is happening or how it is that I would ever be able to solve this on my own.

Attached below is a small js file,index.html file, and a css sheet which I am using to try to create a mini piano.

Problems when I run without debugging are (no breakpoints set):
1: It will often not remove the active class, so the key stays lit.

  • this includes printing out the “keyup” property to the screen but not removing the active class.
    2: It will stop (break) on lines where breakpoints are not set.

Trying to debug the issue creates more unexpected behaviour:
1: when I set breakpoints in functions before the “keyup” section of code (parts associated with “keydown”) is hit, it will not enter the “keyup” section, meaning the active class on the key gets set to true, but does not get removed. It literally just stops processing once it leaves the this part of the code:
> PlayNotes(noteDetail)

// })

It just stops running altogether. (this does not happen when there are no breakpoints)
set)

I have no idea what is going on / causing this, and from what I can tell this is not something I am able to fix on my own.

If anyone can help. Please do ! thank you.

---------------- js file ----------------------

const NOTE_DETAILS = [
  { note: 'C', key: 'Z', frequency: 261.626, active: false },
  { note: 'Db', key: 'S', frequency: 277.183, active: false },
  { note: 'D', key: 'X', frequency: 293.665, active: false },
  { note: 'Eb', key: 'D', frequency: 311.127, active: false },
  { note: 'E', key: 'C', frequency: 329.628, active: false },
  { note: 'F', key: 'V', frequency: 349.228, active: false },
  { note: 'Gb', key: 'G', frequency: 369.994, active: false },
  { note: 'G', key: 'B', frequency: 391.995, active: false },
  { note: 'Ab', key: 'H', frequency: 415.305, active: false },
  { note: 'A', key: 'N', frequency: 440, active: false },
  { note: 'Bb', key: 'J', frequency: 466.164, active: false },
  { note: 'B', key: 'M', frequency: 493.883, active: false },
];

function PlayNotes(noteDetail) {
  NOTE_DETAILS.forEach((noteDetail) => {
    const keyElement = document.querySelector(
      `[data-note="${noteDetail.note}"]`
    );
    keyElement.classList.toggle('active', noteDetail.active || false);
  });
}

function playNoteDetail(noteDetail) {
  console.log(noteDetail);
}
//2
function getNoteDetail(keyboardKey) {
  return NOTE_DETAILS.find((note) => `Key${note.key}` === keyboardKey);
}
//1
document.addEventListener('keydown', (e) => {
  if (e.repeat) return;
  keycode = e.code;
  console.log('keydown', e);
  const noteDetail = getNoteDetail(keycode);
  if (noteDetail == null) return;
  //3
  noteDetail.active = true;
  //4
  PlayNotes(noteDetail);
});

document.addEventListener('keyup', (e) => {
  //debugger;
  console.log('keyUp', e);
  const noteDetail = getNoteDetail(e.code);
  if (noteDetail == null) return;
  const keyElement = document.querySelector(`[data-note="${noteDetail.note}"]`);
  keyElement.classList.remove('active');
});

---------------- index.html ----------------------

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Midi Piano</title>
 <link rel="stylesheet" href="styles.css">
</head>
<body>
  <div class="piano">
    <div data-note="C" class="key white"></div>
    <div data-note="Db" class="key black"></div>
    <div data-note="D" class="key white"></div>
    <div data-note="Eb" class="key black"></div>
    <div data-note="E" class="key white"></div>
    <div data-note="F" class="key white"></div>
    <div data-note="Gb" class="key black"></div>
    <div data-note="G" class="key white"></div>
    <div data-note="Ab" class="key black"></div>
    <div data-note="A" class="key white"></div>
    <div data-note="Bb" class="key black"></div>
    <div data-note="B" class="key white"></div>
  </div>
  <script src="script.js" defer></script>
</body>
</html>

---------------- css file ----------------------

*,
*::before,
*::after {
	box-sizing: border-box;
}

body {
	background-color: #143f6b;
	margin: 0;
	min-height: 100vh;
	display: flex;
	justify-content: center;
	align-items: center;
}

.piano {
	display: flex;
}

.key {
	height: calc(var(--width) * 4);
	width: var(--width);
}

.white {
	--width: 100px;
	background-color: white;
	border: 1px solid #333;
}

.white.active {
	background-color: #ccc;
}

.black {
	--width: 60px;
	background-color: black;
	margin-left: calc(var(--width) / -2);
	margin-right: calc(var(--width) / -2);
	z-index: 2;
}

.black.active {
	background-color: #333;
}

The parameter noteDetail on PlayNotes is not the same as the one you put on the forEach callback. As far as I see you do not need access to the elements in the forEach so you can just remove that parameter and the code should work.

function PlayNotes(noteDetail) {
  NOTE_DETAILS.forEach(() => {
    const keyElement = document.querySelector(
      `[data-note="${noteDetail.note}"]`
    );
    keyElement.classList.toggle("active", noteDetail.active || false);
  });
}

I’ve edited your code for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.

You can also use the “preformatted text” tool in the editor (</>) to add backticks around text.

See this post to find the backtick on your keyboard.
Note: Backticks (`) are not single quotes (').

Thank you for pointing that out lasjorg, you are right on that piece and it should be changed. It makes no difference to the execution of the code though, which is basically a load of nonsensical giant mess:

1: I place breakpoints in the keydown codeblock, then when I hit a key, line of control gets to the end of the keydown (completes that code) codeblock then just stops. But the key has been released, so it should be continuing to the keyup code block… but it does not.
2: If I don’t place any breakpoints on the keydown code block, but place some on the keyup codeblock instead, then hit a key, it will often break at start of the keydown code block, where there are no longer any breakpoints, (as though there is a breakpoint there, but there is not !) So basically repeating the problem in point 1. Or it will sometimes just complete keyup code block as expected.

And yes, apologies for not placing the code with 3 backticks, is there anywhere when writing a post that is says to do this? If not I will try to remember. Thank you.

Update*
After finding a working version of the app I am trying to make and attempting to debug it, I am experiencing the exact same issues with the debugger in vscode.

  • The program will not execute when in debugging mode and displays erratic and unpredicable behaviour.
  • Are there problems with vscode / debugging js or keyboard events I am not aware of? This is quite dissapointing. I am sure others must have experienced this problem, at least when debugging using keyboard events or other areas if the issue is not confined to just keyboard events.

Again thank you for your help.

I’m not sure what you are describing is unexpected behavior. I don’t think there is a way for the browser to break on keydown and still listen for the keyup event with the debugger running. So it can’t break on both, and breaking on keydown will cause the keyup event to get ignored so the key gets “stuck” in the keydown visual state. The same will happen if you use “Break on - attribute modification” for the class add/remove.

I’m not sure what exactly it is you are trying to debug but if you add a transition to the CSS you might be able to use the transitionstart and transitionend events to do some debugging.

" I don’t think there is a way for the browser to break on keydown and still listen for the keyup event with the debugger running. So it can’t break on both, and breaking on keydown will cause the keyup event to get ignored so the key gets “stuck” in the keydown visual state. "

Thanks for pointing that out, lasjorg. I was not aware the debugger acted like this. This is what I was trying to figure out. Does anyone know if there is a “list of sorts” anywhere which details the situations where we may run into debugging scenarios like this? (The ide won’t debug as per normal due to whatever factors?) I know you have already mentioned one other situation above lasjorg.

Nothing particular comes to mind. There are probably some different edge cases with debugging async code that might be somewhat related to this issue.

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.