Teacher's Guide: Event Objects Notes
Overview
This lesson presents a straightforward yet powerful extension of the Keyboard Events! lesson. Event objects provide a range of additional, contextual information about their corresponding events. In the case of keyboard-related events, they also permit us to effectively bind events for all keys with a single event listener, thereby substantially reducing the amount of coding required for many applications. Additionally, this lesson formally introduces two additional Pencil Code keyboard-related event binding functions, keyup
and keypress
, which facilitate a more finessed response to computer keyboard input than can be accomplished with keydown
alone.
More about the lesson
Pencil Code key-event-binding functions
The Pencil Code keypress
and keyup
functions are analogous to the previously-introduced keydown
function. The sole difference between the functions is the event to which they bind. As the name suggests, keyup events fire when a key is released. The difference between keypress and keydown is more nuanced. For example, keydown events tend to fire for any key, including meta characters such as shift or arrow keys, whereas keypress events fire only for keys with visible output. The similarities and differences between these events will be discussed below. But first, we address issues of usage.
The Keyboard Events! lesson introduced keydown
as a function that takes two arguments: a string identifying a key and a callback that the event listener will execute every time that key is pressed, i.e., the event handler. All three keyboard-event-binding functions can be called this way. For example, the following snippet creates a keypress event listener for the lower-case w key:
cbW = ()-> jumpto random(position) label "w", fontSize:"50px", color:random(color) keypress "w", cbW
This two-argument usage is useful when we only need to establish event bindings for only a few keys, such using W, A, S, and D to control sprite movement. However, adding listeners key by key is an inefficent and cumbersome approach for binding larger numbers of keys.
The current lesson introduces the Pencil Code keypress
function as an event binding function that takes a single argument: just the event handler, with no reference to a specific key. Though not stated explicitly in the lesson, all three keyboard-event-binding functions (keydown
, keypress
, and keyup
) can be called this way.
This alternative, single-argument usage of Pencil Code's keyboard-event-binding functions makes it possible to bind all occurances of each event type to a single event handler in one line of code. For example, in the following snippet, keypress cbAnyKey
binds all keypress events to the cbAnyKey
callback. Afterwards, pressing any key will print its character to a random location on the screen:
cbAnyKey = (e)-> jumpto random(position) label e.key, fontSize:"50px", color:random(color) keypress cbAnyKey
Rather than identify a specific key when setting up an event listener, this approach makes use of data about the event itself within the body of the event handler callback. This data is automatically passed to the callback by the event source as an argument in the form of a system-generated event object. Writing the event handler to explicitly accept the event object (the argument e
in the example above) facilitates accessing it in the body of the handler.
Event objects provide a wealth of information about each event. In the case of keyboard events, this information includes not only the key that was pressed, but also a timestamp, a record of concurrently-pressed meta-keys (such as shift or control), and more.
Difference between keyboard events
As just noted, the syntax for the keydown
, keypress
, and keyup
keybinding functions is identical. The differences between the functions owe to the differences between the underlying keyboard events.
The keyup event parallels the behavior of the keydown event. As the name suggests, the keyup event (generally) fires upon release of a key rather than when the key is engaged. One exception to this rule is for the caps lock key: the keyup event does not fire when caps lock is initially pressed and released, i.e., engaging the lock. Rather, it fires upon the subsequent press (not release) of caps lock, which releases the lock. Another important exception invovles the delete key. keyup is the only event that fires when the delete key is pressed and released.
keydown and keypress events differ in a variety of often nuanced, context-dependent ways. For the purpose of the activities in this lesson, the following general rules will typically suffice:
- With a few exceptions (such as for the delete and caps lock keys), keydown events fire whenever a key is pressed. keypress events only fire when the key press produces a character value. Thus both will fire for the keystroke a but only keydown will fire when esc, → or shift is pressed.
- keypress and keydown event objects both have boolean properties that report the status of modifier keys, e.g.,
shiftKey
,metaKey
, andaltKey
. They differ, however, in that for keypress (but not keydown) the value of the event object'skey
andkeyCode
properties reflect the status of modifier keys such as shift or alt (a.k.a., option on Macs). In Pencil Code, this means that if shift is depressed while either event occurs, thekey
value for a keypress event will return an upper-case letter for keys A through Z and characters such as ! and @ rather than the number values 1 and 2. In general, keypress should be the preferred event when processing text.
Finally, there is the issue of timing: keypress and keydown fire prior to keyup.
Notes to activities
The KeyEventNuances activity is designed to encourage students to explore the differences between the events associated with different keybinding functions along several dimensions. The primary issues to explore relate to "if" and "when" events fire. For example, keypress and keydown fire prior to keyup, and keypress will not fire at all when the arrow keys are pressed. The event object's timeStamp
property can be helpful for documenting the sequencing of the different events for a given keyboard action and for exploring the timing of automatically re-firing events (as happens when keypress and keydown are pressed and held, rather than immediately released). Finally, students might also explore how modifier keys, such as shift or control, affect the values of event object properties.
The lesson provides this example solution to the KeyEventNuances activity. It's approach focuses on a narrow subset of event object properties (key
, keyCode
, and timeStamp
). This alternative script provides another look, highlighting some other important differences between keypress and keydown events.
The String class's split
method is a useful shortcut for TypingTest. split
takes a single argument, which specifies the delimeter: abc.split(" ")
breaks up a single string into an array of words; abc.split("")
splits the string into its component letters.
The instructions for the Piano program recommend the use of tone
, an alternative to the play
function. Pencil Code provides this documentation:
A helpful alternative usage not mentioned in this documentation is the fact that tone
's first argument, which specifies the note, can also be expressed a string (e.g., "A", specifying the note name) rather than a numeric value (e.g., 440, specifying the frequency).
Students have several options to map and bind keyboard keystrokes to individual musical notes. A common approach is to use nested if
statements to test whether the event object's key
value matches an appropriate string. However, such nested if
statements can get rather cumbersome. switch
statements (documented below) provide an alternative means to code the same conditional logic more succinctly. The use of switch
is illustrated in the lesson's example solution. Yet another approach, illustrated in this script, makes use of a collection of objects that maps each keyboard key to the respective musical note, e.g., [{key:"a",note:"C"},{key:"w", note:"^C"}]
. Each time a keyboard event fires, iterate over this array of key-and-note objects to determine which of one matches the event object's key
property.
An additional solution to the Piano activity is provided in the Pencil Code Gym. This Interactive Keyboard script also uses keydown
and keyup
event binding functions, but it uses some advanced features not yet explored in this curriculum: anonymous functions, the delete
function, and subscript notation.
Additional activities
- Run this FourIsCOSMIC program a few times, until you figure out the riddle. Once you do, code your own version of the script. You might save your time by limiting the input options to the numbers 1 to 20.
InputBox: The Pencil Code
read
function facilitates text entry in the Pencil Code environment.read
accepts two arguments: (1) a string specifying a prompt and (2) a callback that defines what to do when data entry is complete.name = undefined updateName = (txt)-> name = txt read "Please enter your name: ", updateName
The foregoing snippet produces the following output on screen:
After the user enters data and then either presses enter (on a PC) or return (on a Mac), or clicks the Submit button, this output changes to the following:
read
is useful for students who are new to coding, but for more advanced coders, it is rather restrictive. For example, the way that the text entry box disappears after you enter data, and then the text you entered appears as a label on the screen, is nice for some purposes, but more generally that behavior could be problematic. For example, we might want to keep the text entry box on the screen for continued use. Alternatively, you might want to interact with the user as they enter text into the box, such as for text validation purposes.Using the techniques described in this lesson, students should have little need for the
read
function. However, it does suggest an alternative means by which we may prompt users to enter data, i.e., using the same kind of text entry box. This is accomplished using an HTML <input> element. <input> is a familiar page element for end users and useful because it facilitates letting the user enter and or modify text prior to submitting it.For this activity, code your own InputBox program that makes use of an <input> element to gather information from the end user. In Pencil Code, you can easily add a specific type of HTML element using the
Sprite
constructor, e.g.,inputBox = new Sprite("<input>")
To attach the event listener to the specific page element, rather than the entire document (which is the default), simply use dot notation
inputBox.keypress(callback)
Note that we bind the callback to keypress events so that the value of the event object's
key
property reflects modifier keys such as shift. You should use conditional logic in your callback to test for when the enter / return button is pressed (i.e., whene.keyCode==13
), at which point your program should make use of the input in some fashion.Pro tip: you can manually keep track of each character the user types using the event object's
key
value. However, a much easier approach is to use the jQueryval
method. When a jQuery object wraps an <input> element,val
lets you access or modify the content of the text: e.g.,box.val()
returns the current value andbox.val("x")
replaces the content with the string "x".RPN Calculator: Most calculators and computers base their computations on infix notation, in which operators are placed between operands. Two alternatives to infix notation are prefix notation, in which operators precede their operands, and postfix notation, in which operators follower their operands. Here is how you'd sum five and six, using each approach:
- infix notation: 5 + 6 enter
- prefix notation: + 5 6 enter
- postfix notation: 5 enter 6 +
Prefix and postfix notation have the advantage that they do not require parentheses. These latter two notations are known as Polish notation and Reverse Polish notation (RPN). The description "Polish" refers to the nationality of Jan Łukasiewicz, who invented Polish notation in 1924. RPN is used in scientific and financial calculators made by Hewlett Packard and the logic also undelies some programming languages, most notably LISP.
For this task, code your own RPN Calculator. Rather than bind each key directly, make a single listener for all keys and evaluate the key event for the relevant inputs. Naturally, you will need to program the calculator-computation logic as well!
To carry out a computation using RPN, type the first operand (i.e., value), press
, type the second operand, and then the operator (e.g., "+" or "*"). A more complicated expression such asenter 7*(3+5)
would be computed as7
,
,enter 3
,
,enter 5
,+
,*
.
Beyond the lesson
jQuery event objects and properties
The Notes to the Keyboard Events! lesson described in some detail the structures that faciliate working with events in JavaScript. In summary, GUI-related system events (such as keyboard and mouse events) originate in the underlying operating system. The OS passes information about each event to the system's currently-active program. When that program is a web browser, the browser uses the HTML Document Object Model (DOM) to identify which page element the event affects. If the system event matches an event listener registered for that page element, JavaScript will invoke the corresponding event handler, passing along to that callback, upon execution, a JavaScript event object containing information about the event.
Pencil Code relies heavily on the jQuery library, not only for animations, but for it's event-handling features as well. As a result, students using the Pencil Code event binding functions typically won't interact directly with native JavaScript event objects, but rather with jQuery "wrapper objects" of the underlying JavaScript objects. The benefit of using jQuery is that it provides additional functionality and cross-browser consistency compared to plain JavaScript. Conceptually, the role of JavaScript and jQuery event objects is exactly the same. On a practical level, the difference is that the event object properties mentioned in these notes are all jQuery event object properties. This become important when students want to look up information about specific events.
When working on keyboard events, students will likely focus primarily on the key
, timeStamp
properties and a few others that were mentioned in the lesson. For a complete listing, refer to the jQuery API for Event Objects. Alternatively, one can explore the event object by iterating over it, as illustrated for keydown events in this script.
Technical note: jQuery objects are termed "wrapper" obects because they retain a reference to the native JavaScript object as one of their properties. In the case of event objects, this reference is provided by the jQuery originalEvent
property. Though not common, it can be useful to access the original event. See the Technicalities section of this document for an example.
As noted above, explicitly naming the argument in the callback function's definition—such as e
in the example above—facilitates accessing the event object in the body of the callback. The alternative is to rely on JavaScript function's built-in arguments
argument, as described in the Technicalities section of the Notes to the Custom Functions! lesson.
switch
statements
As noted briefly in the Notes to the Conditional Logic! lesson, a switch
statement provides a convenient alternative to nested if
/else
statements. There are some variations in usage; the basic CoffeeScript switch
statement syntax is straightforward:
switch when condition1 statement(s) when condition2 statement(s) else statement(s)
The CoffeeScript then
operator allow us to combine conditions and single-line statementse, anologous to how then
can be use with if
statements:
switch when condition1 then statement when condition2 then statement else then statement
switch
statements are particularly useful in the context of keyboard events because they facilitate evaluating event object properties, such as key
or keyCode
, that can take on a wide range of potential values. The following snippet illustrates one way we might evaluate the event object for a keyboard event handler with parameter e
:
switch when e.key=="up" fd 100 dot blue, 10 when e.key=="down" dot erase, 10 bk 100 when e.key==right" then rt 90 when e.key=="left" then lt 90 else see "Invalid input: #{e.key}"
An alternative switch
-statement syntax is useful for cases, like the one above, where there is a lot of redundancy in the conditional statements testing for equality. As the following example illustrates, CoffeeScript permits splitting the test for equality into two expressions, and these are implicity compared for equality:
switch e.key when "up" fd 100 dot blue, 10 when "down" dot erase, 10 bk 100 when "right" then rt 90 when "left" then lt 90 else see "Invalid input: #{e.key}"
This next and final example illustrates yet another variation of the CoffeeScript switch
statement, which takes advantage of the CoffeeScript feature that "everything that can be an expression is structured to be one". CoffeeScript permits replacing multiple redundant assignments, i.e., one in each when
clause, with a single assignment to the switch
statement itself.
result = switch when e.keyCode>=97 and e.keyCode<=122 "an uppercase letter" when e.keyCode>=65 and e.keyCode<=90 "a lowercase letter" when e.keyCode>=48 and e.keyCode<=57 "a number" else "neither a letter or a number"
For more details about switch
, please refer to other CoffeeScript resources, such as this one by TutorialsPoint.
Keyboard event sources: tabable HTML elements
As described in the notes to the Keyboard Events! lesson, each call to a Pencil Code keyboard event binding function effectively binds a callback to the web page's <body> element. As a result, the event listener fires the event handler whenever a key associated with that event is pressed.
Binding keyboard events to <body> is a convenient setup for beginners, but it will be limiting in time. For example, students may wish to explore using the HTML <input> element to gather text input, as suggested in one of the additional exercises. Moreover, the ability to bind callbacks to different event sources becomes indispensible when working with mouse events, the topic of the next lesson.
Using dot-notation, we can use event binding functions to register event listeners with page elements other than the the whole page. For example, the following example uses the Sprite
constructor to create a <textarea> element in the middle of the screen. It then attaches the event handler cb
using textarea.keypress
:
textarea = new Sprite("""<textarea rows=5 cols=50></textarea>""") cb = (e)-> jumpto random(position) dot random(color), 50 label e.key textarea.keypress cb
Note, however, that when working with keyboard input, associated events will only fire for page elements that are tabable. "Tabable" means that the element is reachable via sequential keyboard navigation, i.e., with the tab key. (Tabable elements can also be selected using a mouse click.) The <body> element is by default tabable, but most other page elements are not. The exceptions include text-related elements such as <input>, <textinput>, <form>, and <textarea>.
Technical note: Most non-tabable elements can be made tabable by adding a tabindex
attribute with an integer value. The easiest choice is to choose 0
, which simply adds them in order of appearance in the document source. An illustration is provided in this script.
Be aware, however, that adding listeners to different page elements can lead to confusing results if listeners for the same event type are also attached to containing elements, such as <body>. Owing to an events feature called propagation, events will fire for both the contained (a.k.a., child or descendant) element as well as for the containing (parent or ancestor) element. Propagation, and ways to control it, will be discussed in the notes to the Mouse Events! lesson.
What can go wrong
key events are not firing!
The preceding sections of these notes have described in detail many of the nuances of working with keyboard-related events. Perhaps the issue most likely to cause confusion is the fact that the different types of events—keydown, keyup, and keypress—do not all fire in response to all keys.
The first, rather straightforward example involves keypress events. These only fire for character keys, i.e., letters, numbers, and punctuation. Notably, this leaves out the arrow keys.
A second, and much more nuanced example involves the behavior of deletion-related keys. The delete key on the Mac behaves the same as backspace← on the PC. PCs typically also have a delete key, with its own behavior. For the keys delete (on the Mac) or backspace← (on the PC), only keyup fires, though this occurs upon releasing the key rather than when pressing it. The associated event object's key
property (also discussed in the next lesson) has value "backspace"
. On the PC, pressing delete does result in keydown and keyup events. The associated event object's key
property has value "delete"
. (See this script for an illustration.)
Variable scope complications
It is common to reference global variables in event handlers. When doing so, note that the variable must be declared prior to calling the event binding function. If not, the variable referenced in the event handler function will be a new variable with function scope. This short script provides a simple illustration.
Event Polling
When learning about keyboard events, students may attempt to create programs that allow them to control sprites using keys. However, such efforts may end in frustration. As described in the instructions to the Additional Activity TurtleWarperGame in the Notes to the Keyboard Events lesson, the use of keyevent-binding functions to control sprite motion is fine for programs that involve simple motions, but it is a suboptimal means by which to control sprite movement more generally. The underlying issue relates to lags associate with key events, a topic explored in these notes in a section on long presses. A superior solution is to rely on frame-based animation using timers and to harness a concept known as event polling, rather than to make use of the event binding fuctions directly. Timers and event polling are the focus of subsequent lessons in this curriculum, Timers (forever)! and Event Polling!.
Pedagogy
Explicitly defined callback functions
As mentioned in the notes to the previous lesson, the coding snippet provided in the Pencil Code block coding palette makes use of anonymous functions, and students and teachers alike may be tempted to adopt this convenience at this point. However, doing so risks diminishing student awareness of the role that callbacks play here. It also blurs the role of arguments used in the keybinding function context.
For example, the following code is the first line of a call to the keydown
function with two arguments:
keydown 'x', (e) ->
An inexperienced coder can easily confuse e
as an argument to keydown
, though it is not. Rather, (e) ->
, together with the subsequent lines of indented code which define an anonymous function, are the second argument to keydown
The upshot is that there continues to be good reason to hold off on anonymous functions. The topic will be addressed directly in the Anonymous Functions! lesson.
Technicalities
Keyboard event nuances
While the concepts and activities in the lesson are straightforward enough, keyboard event objects can be notoriously difficult to process in practice. Many of the nuances of working with events trace to historical cross-browser (and cross-platform) differences between browsers. Admittedly, these differences have become less pronounced over time, but it is still an issue. A primary reason for adopting jQuery is that it frees up coders from having to worry about the many cross-browser differences which would otherwise significanly complicate code. However, when it comes to keyboard events, jQuery is not a panacea.
Over the years, the HTML specifications and the JavaScript langauge have continued to evolve, with some significant changes to keyboard events. A not-to-be-overlooked consequence of this evolution is that different sources for documentation on events will provide divergent and even conflicting approaches to working with events. Quite a few of the properties in event objects have been deprecated over time.
A more far-reaching change is that the JavaScript keypress event itself is now deprecated. The upshot is that, while event bindings with the Pencil Code keydown
and keyup
functions (which internally use calls to jQuery event-event binding methods) can be counted on to provide consistent results across systems, the same may not continue to be true for keypress
: per the the JQuery API, "as the keypress event isn't covered by any official specification, the actual behavior encountered when using it may differ across browsers, browser versions, and platforms."
Details on the deprecation of keypress are provided on the mdn docs page for keypress. The preferred modern alternatives to using keypress involve use of the beforeinput, keydown, or input (this last one new in 2023). However, given that access to the keypress event continues to be facilitated by jQuery, and also that the newer alternatives exceed most student needs while increasing the complexity of use, this curriculum recommends continued reliance on keypress events.
Yet another complicating factor to working with events in the Pencil Code environment is that the Pencil Code key event binding functions are modifications of the underlying jQuery. Some of these modifications were added to simplify the use of event-binding functions, such as adding the two-argument variants (e.g., keydown "x", eventHandler
). Also, as noted above, the default codes from keydown
are lowercase letters, whereas the standard mappings are to uppercase letters. Additional modifications, unseen to the user, include keybinding changes written with the intent to eliminate some persistent cross-browser differences in jQuery.
The upshot of the foregoing conversation is that, for the level of work that students will use at this point in their coding careers, most of the nuances listed in this section are unlikely to surface, but be aware that problems can arise, and also that documentation listed on other sites (MDN web docs for JavaScript, W3schools, jQuery API documentation) will at times give explanations that don't sync with functionality enountered on the Pencil Code platform.
jQuery event-binding methods
As discussed in the notes to the Keyboard Events! lesson, the jQuery keydown
method is a shortcut for a call to the more general and versatile jQuery method on
. The statement keydown eHandler
is synonymous with $(window).on("keydown", eHandler)
. The on
method works analogously for other browser events, including keypress and keyup.
As with the Pencil Code keybinding methods, on
can be called on any jQuery object that references an HTML page element (or collection of page elements). Note that we have to explicitly reference $(window)
(or some other page element wrapped in jQuery) because in CoffeeScript on
is an alias for true
, rather than for the jQuery event-binding method.
The primary benefit to using the on
method rather than keydown
is that you can subsequently use the corresponding off
method to detach the event handler. off
uses a similar syntax. For example,
window.off("keydown", eHandler)
removes the eHandler
callback from the keydown event listener that was established using on
. window.off("keydown")
will remove all keydown event handlers set up using on
. However, off
has no effect on handlers set up with the Pencil Code keydown
function, as illustrated in this script
In addition to the on
method, jQuery also provides its own keydown
, keypress
, and keyup
methods. These are jQuery shortcuts to pure jQuery event binding calls using on
; they are not directly related to the Pencil Code keybinding functions of the same name. For additional details about using jQuery event-binding methods, refer to the jQuery events documentation.
jQuery event object's originalEvent
property
The jQuery library's popularity owes in no small part to how it simplifies writing code that will work in all the different major browsers on all common operating systems. This is no mean feat, as the differences are not only myriad but often highly nuanced, and hence often tedious and time consuming to address.
In the case of events, jQuery creates its own event object that adjusts any system specific features so that they all adhere to these W3C standards. As with objects more generally, jQuery does not simply replace the orginal event, but creates a wrapper object. This jQuery event object normalizes and provides values for "common event properties", which include altKey
, bubbles
, button
, buttons
, cancelable
, char
, charCode
, clientX
, clientY
, ctrlKey
, currentTarget
, data
, detail
, eventPhase
, key
, keyCode
, metaKey
, offsetX
, offsetY
, originalTarget
, pageX
, pageY
, relatedTarget
, screenX
, screenY
, shiftKey
, target
, toElement
, view
, and which
.
The foregoing list may seem extensive, but it is not complete. It does not include properties for which the W3C does not provide a standard. The jQuery originalEvent
property provides access to the event object that the browser itself created, and thus to the properties not included in the jQuery object directly.
Long presses / auto-repeat
An example of a property not included in the jQuery event object relates to "long presses". When a key is pressed and held, keydown and/or keypress events will fire repeatedly until the key is released. (In the case of keydown events, this holds only for keys that produce output, such as letters, and for arrow keys, but not for modifier keys such as shift or alt). .
Though the jQuery event object does not have a property to track whether a keyboard event fires as the result of an initial key press or from a repeat, the JavaScript event objects of each of the major browsers do.originalEvent.repeat
records a boolean value indicating whether the event was a repeat fire from a single key press.
The following example provides an illustration of how one might access this wrapped object property:
The timing of the auto-repeated events is determined by the underlying operating system. On a MacBook Pro running Chrome, the lag before the first keydown event and the first repeat is about 400ms. Subseqent refirings occur about every 80ms.
These lags between events can produce suboptimal behavior in interactive games when key events are used to control movement. A superior alternative is to use event polling, which is enabled by using timers (facilitate with the foreover
function in Pencil Code), as discussed in the Event Polling! lesson.
JavaScript key event bindings
The "best-practice" approach to adding event bindings using pure JavaScript involves using a page element's addEventListener
method. The following script illustrates this approach by adding a keydown event listener to the <html>
element. (The JavaScript document
variable provides access to the <html> element; see above for more details.) JavaScript listeners can be subsequently removed using the removeEventListener
method.
document.addEventListener('keydown', writeText); function writeText(e) { write(`${e.key} ${e.keyCode}`); }
Compared to JavaScript, the jQuery event binding alternatives have the obvious advantage of simpler syntax. Another advantage to jQuery event binding functions is that they can be used to add event listeners to multiple objects using one function call. Students will explore this functionality in the Mouse Events! lesson.
Legacy approaches to event binding
An alternative approach to adding listeners is to directly assign an event handler to an event property of an HTML page element. However, this approach to event binding is antiquated and considered poor form, and therefore it's use is strongly discouraged. This section is provided solely as a reference—for example, to help a student understand code that he or she may happen across when looking through other JavaScript resources.
To create a keypress event listener, assign a callback to the HTML element's onkeydown
property. One approach for doing this is to use jQuery to identify and manipulate page elements, including assigning the callback, as illustrated here:
$("body").attr('onkeypress', """ cs(); label("You entered " + event.key, 50); $("body").css({backgroundColor:random(color)}); """ )
Note the following nuances to the foregoing example: the argument that defines the callback is passed as a string; the function definition itself must be coded in JavaScript (not CoffeeScript); and the event object is automatically passed to the callback as the variable event
.
Using native JavaScript to identify and manipulate page elements, the previous code can be written as follows:
document.body.onkeypress = function(){ cs(); label("You pressed " + event.key, 50); document.body.style.background=random(color); }
Direct use of the page-element properties to bind events often appears for simple callbacks as inline JavaScript (i.e., defined within the HTML definition of a web page), such as illustrated here :
<html> <body onkeypress = "cs();label("You pressed " + event.key, 50); document.body.style.background=random(color);" > <p>Press a key to change the color.</p> </body> </html>