Here are the things I learned from Day 1 of the JS30 challenge:
We bind an event to our keys when they are pressed, as follows:
I have defined a .play class in CSS which makes the items glow when the corresponding key is pressed
Reminded me of putting the following in every project
<html lang="en-US">
<meta charset="UTF-8">
and optionally
<meta name="author" content="Arjun Khode">
To add the stylesheet, we use href and not src.
<link rel="stylesheet" href="style.css">
-We can find the keyCode of each key on the site keycode.info
What <kbd> does
The HTML Keyboard Input Element <kbd> represents user input and produces an inline element displayed in the browser's default monospace font.
I gave a transparent background to the drum item using rgba()
In box shadow, the 0 0 15px was not bright enough, so I used the 4th parameter ‘spread’ to make the shadow-spread more vivid, as: 0 0 15px 5px
The align-items in the flexbox wasn’t working by default because it had no height of its own. I had to give a height of 100vh to the flexbox element to get the contents to appear in the vertical center.
- JS
We bind an event to our keys when they are pressed, as follows:
window.addEventListener(‘keydown’, function(e){}) //note keydown is in quotes. And it is window, not document.
document stands for DOM
and window is the global object in a browser, or the root object of the DOM
document stands for DOM
and window is the global object in a browser, or the root object of the DOM
Inside the function, we write
const audio=document.querySelector(‘’);
the document.querySelector acts like $() in jQuery
the document.querySelector acts like $() in jQuery
Inside the querySelector, we write
`audio[data-key=“{e.key}”]` //where data-key has to have its value in double quotes, the whole querySelector expression has to be in back ticks (`) for template literal notation and the value is a variable inside the event e, which is called keyCode, a property of event 'e'.
${} is just syntactic sugar. Read more about it here (look for “Expression interpolation”)
So we get
const audio = document.querySelector(`audio[data-key=“${e.keyCode}”]`);
audio.play();
if we keep hitting a key, it needs to rewind to the beginning
so we add,
audio.currentTime=0; before audio.play(); The 0 stands for seconds.
I have defined a .play class in CSS which makes the items glow when the corresponding key is pressed
To add a class to an element, we use item.classList.add(‘className’);
This is the same as element.addClass(‘className’); in jQuery
Instead of removing the class play normally, we remove the play class on the transitionend event of the transform property
Regarding forEach, it is not just forEach but items.forEach(); which means that forEach function is a property of an array.
One final comment:
This app does not work well on Safari because it takes too long for Safari to parse the keydown event.
It works great on Chrome though.
UPDATE:
Here is the code to enable playing by clicking on the buttons as well
//code for click functionality
const items=document.querySelectorAll('.item');
function clickTrigger(){
let key=(this.dataset.key);
const audio=document.querySelector(`audio[data-key="${key}"]`);
const item=this;
item.classList.add('play');
audio.currentTime = 0;
audio.play();
}
function unclickTrigger(){
this.classList.remove('play');
}
items.forEach(item=>item.addEventListener('mousedown',clickTrigger));
items.forEach(item=>item.addEventListener('mouseup',unclickTrigger));
Explanation:
1.Select all item divs and call them "items"
const items=document.querySelectorAll('.item');
items.forEach(item=>item.addEventListener('mousedown',clickTrigger));
items.forEach(item=>item.addEventListener('mouseup',unclickTrigger));
3. Create function clickTrigger and unclickTrigger
4. clickTrigger function explanation:
In clickTrigger, "this" variable will select the particular "item" div clicked.
Inside "this" we have a data-key property.
To access any data- element in JS, we use "dataset" property
So, if you have data-key, it becomes:
dataset.key
Store the data-key of the clicked item in a variable called "key"
let key=(this.dataset.key);
Then using key, select corresponding audio to trigger
const audio=document.querySelector(`audio[data-key="${key}"]`);
(Notice how "key" variable has been slid into the template string)
Then simply add the regular code to add to item a class "play" (for the animation)
and play the audio
audio.play();
5.unTrigger function explanation:
Simply remove the class play from "this" (which is the item div on which mouseup has happened)
This removes the animation
UPDATE:
Here is the code to enable playing by clicking on the buttons as well
//code for click functionality
const items=document.querySelectorAll('.item');
function clickTrigger(){
let key=(this.dataset.key);
const audio=document.querySelector(`audio[data-key="${key}"]`);
const item=this;
item.classList.add('play');
audio.currentTime = 0;
audio.play();
}
function unclickTrigger(){
this.classList.remove('play');
}
items.forEach(item=>item.addEventListener('mousedown',clickTrigger));
items.forEach(item=>item.addEventListener('mouseup',unclickTrigger));
Explanation:
1.Select all item divs and call them "items"
2. Attach mousedown and mouseup events to every item in "items" using forEach
items.forEach(item=>item.addEventListener('mousedown',clickTrigger));
items.forEach(item=>item.addEventListener('mouseup',unclickTrigger));
3. Create function clickTrigger and unclickTrigger
4. clickTrigger function explanation:
In clickTrigger, "this" variable will select the particular "item" div clicked.
Inside "this" we have a data-key property.
To access any data- element in JS, we use "dataset" property
So, if you have data-key, it becomes:
dataset.key
Store the data-key of the clicked item in a variable called "key"
let key=(this.dataset.key);
Then using key, select corresponding audio to trigger
const audio=document.querySelector(`audio[data-key="${key}"]`);
(Notice how "key" variable has been slid into the template string)
Then simply add the regular code to add to item a class "play" (for the animation)
and play the audio
audio.play();
5.unTrigger function explanation:
Simply remove the class play from "this" (which is the item div on which mouseup has happened)
This removes the animation