Attach a Function¶
We've talked about how to attach a function as an event handler in both raw JavaScript and jQuery. Nevertheless, it's a difficult concept and one that many students make mistakes with, particularly with RPS.
You might review these readings:
- raw JS attaches a function using raw JavaScript
- jQuery attaches a function using jQuery
- DOM#h3events is another example from reading on attaching an event handler
- attaching a function example in lecture on attaching a function
- the colors/roses exercise is the solution from our in-class exercises
Rather than give you the answer for RPS, or try to drop clever hints, I'm providing this exercise. While this may seem like a time-wasting detour from getting RPS solved, I hope it will help you solve it more successfully. I'll keep the exercises short.
Overview¶
Here's an overview of what we want to do:
- write some code to print a random number to the console. Let's call that the "action" code.
- execute that code whenever a button is pressed
Here's an example. Open the JS console and click the following button:
Action¶
Let's start with the "action" code (the code we want to do):
console.log(Math.random());
Copy/paste that code into the JS console to assure yourself that it does what you want.
Exercise¶
Here's a button. Its ID is 'b2'.
Write some code to do our "action" whenever the button is clicked. If you can do that, you are ready to return to RPS and attach your event handlers. If you have trouble, read on.
Attach¶
Here's the obvious way to attach that code to b2:
$("#b2").click(console.log(Math.random()));
That doesn't work. Try it! Copy/paste it into the JS console and click the button. No go.
You'll notice that copy/pasting that code into the console does print one random number in the console, but clicking the button has no effect.
Why not?? Please take a moment to think about the answer before reading on.
Hint: the argument to .click()
needs to be a function. The
"action" code above is not a function. It's code, but it's not a
function.
Try the following, by copy/pasting it into the JS console. Check the
value of action
. The code does print a random number into the
console, but the value of action
is undefined
, since that's the
return value of console.log
. And that's what we are
attaching. Unfortunately, jQuery doesn't complain about attaching
undefined
, either.
var action = console.log(Math.random());
$("#b2").click(action);
Create a function¶
Third attempt: Let's package up our "action" code into a function:
function action() {
console.log(Math.random());
}
$("#b2").click(action());
This doesn't work either. It does run our action function and print a random number to the console. But the button is still useless.
Fourth attempt. Let's be really clear about what the event handler is:
var handler = action();
$("#b2").click(handler);
This doesn't work, but now we can see that handler
is
undefined
. That's because action
doesn't return anything.
A Function is not its Value¶
But isn't action
a function? Aren't we attaching action
as the event handler?
No. We are executing action
and attaching its return value as the
event handler. Since its return value is undefined
, we are not
attaching anything as the event handler.
Just to be very clear: the function named action
is not the same
thing as the result of invoking the action
function.
In code, that means:
action != action()
Attaching a Function not its Value¶
If we want to attach the function, rather than its value, we can do this:
$("#b2").click(action);
Try it! Copy/paste that into the JS console and then click the button.
What, what's the difference? Didn't we already try this? No, we did this:
$("#b2").click(action());
Those are different things. The first attaches a function, using its name. The second runs the function and attaches the return value.
Attaching an Anonymous Function¶
Here's a new button. Its ID is 'b3'.
What if we want to attach an anonymous function instead of creating a
named function like action
? We can do that:
$("#b3").click(function () { console.log(Math.random()) });
Try it!
The code above wraps up our action code into an anonymous function
and hands the anonymous function to click
. It's the same as this:
var handler = function () { console.log(Math.random()) };
$("#b3").click(handler);
Functions to Do the Attachment¶
All of the examples above do the attachment at "top-level". In Ottergram, they created a function to do all the attaching, and then they invoked that function.
Here's yet another new button. Its ID is 'b4'.
Here's how we could write a function to do the attaching:
function doAttaching() {
$("#b4").click(function () { console.log(Math.random()) });
}
doAttaching();
Note that we both defined the function doAttaching
and then we
invoke it. We must do both. If you define the function and don't
invoke it, the attachment doesn't get done.
The attaching of the event handler is different from our action code. The action code should not attach itself to the button. Something else does that.
RPS¶
Hopefully, you now feel more confident about attaching functions as event handlers in RPS. If you're still confused and having trouble, please contact Scott or a tutor.
Time and Work
The following link has been updated for Fall 2023.
Finally, when you have completed the assignment, make sure you fill out the Time and Work Fall 2023 That report is required.