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:

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:

  1. write some code to print a random number to the console. Let's call that the "action" code.
  2. 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.