The this Keyword
Here's a challenge you may or may not have considered (as you're implementing the following example with the tools we have thus far, see if you can "feel" what part of your solution is a bit fishy!):
Design a page with a bunch of boxes (divs with a set width and height) such that every time they are clicked, their background-color is changed to something random.
What would be the problem(s) of manually defining box-specific event-handlers for each box?
Many problems! 1) We may not know in advance how many boxes we need to assign behavior to, and so creating a finite set of different event handlers is out of the question; 2) we MAY know how many boxes we have to make do something, but what if it's, say, in the 100s?! Nobody got time for that!
So, we need some mechanism that would allow us to refer to individual boxes in a templated fashion so that we can assign the same event handler to a bunch of elements, but have that single event handler elicit (possibly) different behavior for every individual.
For this task, we'll use the this keyword, which has applications outside of event handlers, but we'll talk about its usage in this domain first.
When used inside of a selected DOM element's event handling function, the this keyword returns a reference to that selected element from inside of the function.
(the above definition is just a special case of using this from within an object's method, but that's a topic for another day!)
Here's an implementation that employs JavaScript's template literals, which are useful for templating strings with variable values spliced in the middle.
See the Pen Disco Boxes by Andrew Forney (@forns) on CodePen.
Keypress Event
We've been harping on the onclick event handler but there are plenty of other good ones!
Let's look at another modality now: the keyboard.
The keypress event is one that can be handled by the document object itself, detecting any global keypresses.
In general, an event object is a parameter passed into specific event handlers that provides details about the event.
The anatomy of the onkeypress event handler looks like this:
document.addEventListener("keypress", function (event) {
// Any event-handling behavior here, though take a
// look at the event object in the console!
console.log(event);
});
In particular, if we expand the objects in the console.log, we see that the keypress KeyboardEvent object contains lots of useful information, for example:
event.key: a string of whatever key was pressed.event.shiftKey: a boolean property that tells you if the shift-key was held down while typing the given key. Similar properties:event.altKey,event.controlKey.
Here's a quick example: we'll help Agent Yenrof put a secret report-filing mechanism in our websites whenever he types a capital Y on the page.
document.addEventListener("keypress", function (event) {
if (event.key === "Y") {
alert("Welcome back, Comrade");
let report = prompt("Enter your report now:");
// TODO: do something with that report :P
}
});
Timed Events
"Timing is everything!" Or so they told me at clown college.
Sometimes we need to integrate time into our scripts, not to mention our event handlers!
There are two important time-related mechanisms for us to consider:
The setTimeout function allows us to execute some behavior once some number of milliseconds have passed.
The anatomy of the setTimeout function is as follows:
setTimeout(function () {
// Behavior here
}, milliseconds);
// OR:
function funName () {
// Behavior here
};
setTimeout(funName, milliseconds);
Suppose I wanted to make a "slowpoke" button that alerts "hi!" 3 seconds after it's clicked. I could do the following:
<html>
<body>
<button id="slowpoke">Slowpoke</button>
</body>
</html>
document.querySelector("#slowpoke").addEventListener("click", function () {
setTimeout(function () { alert("hi!"); }, 3000);
});
The setInterval method allows us to execute a function repeatedly, once every given number of milliseconds.
The anatomy of the setInterval method is the same as setTimeout, except with "setInterval" as the function name.
Suppose we wanted to design an annoy-o-script, we could do something like:
setInterval(function () {
alert("Hi! can I help you?");
}, 3000);
The setInterval method returns an interval ID that can be used to uniquely identify the repeated behavior on the page.
If at some point you wish to stop the execution of an interval's repetition, you can use the clearInterval(intervalID) function.
So, for example:
let annoyId = setInterval(function () {
alert("Hi! can I help you?");
}, 3000);
// ...some time later, after some criteria is met:
clearInterval(annoyId); // Stops executing the alerts
Events in p5.js
Did you think I'd forgotten about p5? Of course not; we don't just make our rockets and then fly away!
p5.js has its own event handling mechanics as well! Click here to see them!
In particular, we can examine the mouse click event handler to do some target practice!
Design a simple target practice game that scrolls a moving target along the p5 canvas, and then alerts "Bullseye!" when the user clicks on the moving target!
We'll need a couple new tools in our arsenal for this one! In particular, we should be aware of:
The mouseClicked function, which p5 calls every time a mouse click event occurs.
The mouseX and mouseY variables, which are set to the pixel coordinates of the mouse click.
So, to accomplish our task at hand, all we need to do is make sure the distance of the mouse click and our target is small enough to consider it a "hit!"
To compute this distance, we can also employ the p5 dist function.
The dist(x1, y1, x2, y2) function computes the Euclidean distance between the two given points.
Let's try a simple implementation now!
See the Pen Target Practice by Andrew Forney (@forns) on CodePen.