Help on Project: Piano Keys

// The keys and notes variables store the piano keys
const keys = ['c-key', 'd-key', 'e-key', 'f-key', 'g-key', 'a-key', 'b-key', 'high-c-key', 'c-sharp-key', 'd-sharp-key', 'f-sharp-key', 'g-sharp-key', 'a-sharp-key'];
const notes = [];
keys.forEach(function(key){
  notes.push(document.getElementById(key));
})

// Write named functions that change the color of the keys below
const keyPlay = function(event)
{
  event.target.style.backgroundColor = "#FF5733";
}
const keyReturn = function(event)
{
  event.target.style.backgroundColor = "";
}
// Write a named function with event handler properties
let eventHandler = function(note)
{
  note.onmousedown = function()
  {
    keyPlay(event);
  }
  note.onmouseup = function()
  {
    keyReturn(event);
  }
}

// Write a loop that runs the array elements through the function
notes.forEach(eventHandler);

So far, my code works fine since I’ve been following along with the video that accompanies this project. However, I am a little confused on steps 4 and 5, where I am creating event handlers for the “keyPlay” and “keyReturn” functions. I do not understand why the argument passed into the keyPlay and keyReturn functions inside the “onmouseup” event handler function is “event”. Can someone please explain to me why this works? Thanks!

When an event occurs the environment creates an object to capture all the details of that event. Given that even mouse movements are among those events we can appreciate how transient the object is that describes these events as they occur in real time. Needless, there can only ever be ONE event object at any one time. Using event captures (listeners) allows us to channel behaviors (handler functions) and effect a redraw of the browser window with new, pertinent information, even if it is just a wink from an emoji.

Thanks for the insight! I just wanted to clarify, the term “event” that we pass into the keyPlay and keyReturn functions is not a variable, so it must be a special keyword in javascript then?

It can be a variable we create, but it is inevitably referring to the EventObject if that’s the context we are passing to the handler.

an event takes place (trigger)

An event object is created every time there is a new event. There’s only ever one of these in execution context at any one time.

If we view that execution context as an object, more particularly, a global object, then it is easy to conceive of it as having an event property since these things are prone to occur. This gives rise to the global event object. (window is the only object at the top of the scope chain, and does not need to be specified.)

It’s easy to see how we could be confused by the two descriptions given above. One WE name, event, and the other IS NAMED, event.

Master this, and event bubbling and you pretty much have it.


Now that we know of a potential conflict, both systemic and human, it makes good sense to resolve some avoidance protocol. That avoidance would be the global object. Sure it will be fine to pass it along, but never to assume it.

This means never using listeners that are not attached to some other object than window. Escape the global realm and attach listeners to their respective objects in the formal manner.

object.addEventListener(callback)