Code-Along: Funktional Functions
In this code-along, add some funktionality to buttons on a website using callbacks.
Setting Up
Click here to go to the Funktional Functions Starter project.
Start by copying the project. Take a look at the current code in the script.js file:
bassAudioobject andplayBassfunction definition - these make it possible to play an audio track!chooseRandomfunction definition - this makes it possible to choose a random item from an array, and exclude any item in particular- Many
document.querySelectorcalls - these will all store HTML elements in variables to make them easier to access later in the code
There is a lot of setup, but nothing is actually functional yet. Run the project and notice that none of the buttons actually work!
Hooking Up the Bass Button
All of the bass-playing functionality is ready to go, but the function is not being called anywhere! Hook it up to the button with addEventListener.
- Open the index.html file
- Notice the "🎸 ⏯"
<button>element has anidof"play-pause-bass" - Open the script.js file for editing
- Notice the
playPauseBassButtonvariable stores the proper HTML button - Make a new line at the bottom of the file
- Call
addEventListeneron theplayPauseBassButtonobject - Pass in
"click"as the first argument - Pass in
playBassas the second argument- Note: this is the actual function as a variable, not a function call!
Run the project again, click the "🎸 ⏯" button, and verify that Bootsy Collins starts playing!
The added line of code should look something like this:
playPauseBassButton.addEventListener("click", playBass);
Defining the Random Background Filter Function
Now the "🎸 ⏯" button is good to go - the next button to hook up is the "Swap Color" button. This one doesn't have a function defined yet, but the function should change the background filter to a random color.
- Make a new line at the bottom of the script.js file
- There, create a new variable named
randomBgFilter - Set
randomBgFilterto be a new functionfunctionkeyword- Parentheses
- Curly brackets
- In the body of the function (between
{and}), make a new line - There, set the
backgroundColorofbackgroundFilterDiv.styleto"yellow"
Nothing will change quite yet... the randomBgFilter function still needs to be hooked up to the proper button! The new function code should look something like this:
let randomBgFilter = function() {
backgroundFilterDiv.style.backgroundColor = "yellow";
}
Hooking Up the Swap Color Button
Now a basic version of the function is ready, but it needs to be hooked up.
- Open the index.html file
- Notice the "Swap Color"
<button>element has anidof"color-swapper" - Open the script.js file for editing
- Notice the
colorSwapperButtonvariable stores the proper HTML button - Make a new line at the bottom of the file
- Call
addEventListeneron thecolorSwapperButtonobject - Pass in
"click"as the first argument - Pass in
randomBgFilteras the second argument- Note: this is the actual function as a variable, not a function call!
Run the project again, click the "Swap Color" button, and verify that the filter changes to yellow!
The added line of code should look something like this:
colorSwapperButton.addEventListener("click", randomBgFilter);
Filling Out the Random Background Filter Function
At this point, the randomBgFilter function is doing something, but it's not working quite right. Instead of only setting the color to yellow, it should choose a random color from an array.
- Make a new line at the top of the body of the
randomBgFilterfunction - There, create a new variable named
currentColor - Set
currentColortobackgroundFilterDiv.style.backgroundColor- This is the current filter color so the function can make sure it's a new color this time
- Under that, create a new variable named
colors - Set
colorsto be an array containing red, orange, yellow, cyan, green, and purple - Under that, create a new variable named
randomColor - Set
randomColorto be a call tochooseRandom- This function is defined earlier in the script.js file
- Pass in
colorsas the first argument, andcurrentColoras the second- This will choose a random color while avoiding the current color
- Next, change the
"yellow"torandomColorso it uses the randomly chosen color
Run the project, click the "Swap Color" button a bunch, and verify that there is a new color each time! The body of the randomFilterBg function should look something like this:
let currentColor = backgroundFilterDiv.style.backgroundColor;
let colors = ["red", "orange", "yellow", "cyan", "green", "purple"];
let randomColor = chooseRandom(colors, currentColor);
backgroundFilterDiv.style.backgroundColor = randomColor;
Defining the Start Cycle Function and Hooking Up the Button
Now, it's pretty funkalicious that the background color can change. However, it would be even more funkalicious if it could happen automatically! This is possible with setInterval, and the randomBgFilter function already defined.
- Make a new line at the bottom of the script.js file
- Define a new function named
startCyclefunctionkeyword- Function name (
startCycle) - Parentheses
- Curly brackets
- In the body of the
startCyclefunction (between{and}), make a new line - There, call the
setIntervalfunction - Pass in
randomBgFilteras the first argument, and250as the second- This will cause the function to run once every 250ms
- Outside the function definition, make a new line
- Hook up the
startCycleButtonto run thestartCyclefunction when clicked- Use
startCycleButton.addEventListener
- Use
Run the project, click the "Start Cycle" button, and see the colors cycle automatically!
The code should look something like this:
function startCycle() {
setInterval(randomBgFilter, 250);
}
startCycleButton.addEventListener("click", startCycle);
Stopping the Cycle: Tracking the Cycle Interval Id
Now the cycle has begun, but there is no way to stop it! That could get annoying. Luckily, there is a way to keep track of any currently running function intervals - the setInterval function will return an ID value that can be used to track its usage.
- Make a new line above the
startCyclefunction definition - There, define a new variable named
cycleIntervalId(do not set it to anything) - In the body of the
startCyclefunction, setcycleIntervalIdto the value returned fromsetInterval - Next, wrap the
setIntervalcall in anifstatement - For the
ifcondition, check ifcycleIntervalIdis unset using!cycleIntervalId- This means there is not currently an interval running
This will not change any functionality yet, but it will now be possible to stop the interval. The added code should look something like this:
let cycleIntervalId;
function startCycle() {
if (!cycleIntervalId) {
cycleIntervalId = setInterval(randomBgFilter, 250);
}
}
Defining the Stop Cycle Function and Hooking Up the Button
All that's left is to define a new function to stop the cycle, and hook it up to the proper button.
- Make a new line at the bottom of the script.js file
- There, define a new function named
stopCycle - In the body of the
stopCyclefunction, call theclearIntervalfunction - Pass in
cycleIntervalIdto theclearIntervalcall- This will stop the
startCyclefunction from running
- This will stop the
- Under that, still in the body, set the
cycleIntervalIdtonull- This ensures that a new cycle will be able to start
- Outside the function definition, make a new line
- Hook up the
stopCycleButtonto run thestopCyclefunction when clicked- Use
stopCycleButton.addEventListener
- Use
Run the project, start the cycle, and make sure the "Stop Cycle" button makes it stop! The code at the bottom should look something like this:
function stopCycle() {
clearInterval(cycleIntervalId);
cycleIntervalId = null;
}
stopCycleButton.addEventListener("click", stopCycle);
Conclusion
This code-along showed a small sample of what is possible with event listeners and intervals. Almost anything on a website can be controlled with these tools!
By the end of the activity, the additional code in the script.js file should look something like this:
// Hook up Bass Button
playPauseBassButton.addEventListener("click", playBass);
// Define a function to change the background to a random color filter
let randomBgFilter = function() {
let currentColor = backgroundFilterDiv.style.backgroundColor;
let colors = ["red", "orange", "yellow", "cyan", "green", "purple"];
let randomColor = chooseRandom(colors, currentColor);
backgroundFilterDiv.style.backgroundColor = randomColor;
}
// Hook up the "Swap Color" button to call the function
colorSwapperButton.addEventListener("click", randomBgFilter);
// Prepare Interval ID - this will keep track of the currently running function
let cycleIntervalId;
// Start the cycle if there is not one currently running
function startCycle() {
if (!cycleIntervalId) {
cycleIntervalId = setInterval(randomBgFilter, 250);
}
}
// Hook up Start Cycle Button
startCycleButton.addEventListener("click", startCycle);
// Stop any currently running cycle
function stopCycle() {
clearInterval(cycleIntervalId);
cycleIntervalId = null;
}
// Hook up Stop Cycle Button
stopCycleButton.addEventListener("click", stopCycle);