Home Blog CV Projects Patterns Notes Book Colophon Search

Maintaining Scope in JavaScript Event Handlers via a Closure

29 Aug, 2008

The example below and its comments should be self-explanatory:

<html>
<head></head>
<body>
<!--
This example demonstrates how to use a JavaScript closure to ensure that
an event handler can access variables passed to a create_handler() function
from the scope of the code in which the handler is assigned.

Ordinarily if you didn't use the closure and the variable which was
passed to the function changed its value the handler would
have the new value, not the value of the variable at the time
it was passed to the handler.

Here we only pass one argument but you could modify create_handler()
to pass more variables if needed.
-->
<div id="keep_element">Click me! I keep my value.</div>
<div id="lose_element">Click me! I lose my value.</div>
<script language="javascript">
function create_handler(arg){
    // Return a reference to an anonymous inner function created
    // with a function expression:-
    return (function(e){
        // This inner function is to be executed on the event
        // and when it is executed it can read, and act upon, the
        // parameters passed to the outer function, as well as have
        // access to the event.
        alert(arg+' Plus, we\'ve got access to the event: '+e);
    });
}
// Get the elements we want to add the handler to
var keep_elem = document.getElementById('keep_element');
var lose_elem = document.getElementById('lose_element');
// Create a variable
var msg = 'The original value.';
// Add the onclick handler so that when it is called it uses the value
// a at the time the handler was added.
lose_elem.onclick = function(e) {
    alert(msg+' Plus, we\'ve got access to the event: '+e);
};
keep_elem.onclick = create_handler(msg);
// Set a to a different value, this won't affect the value which
// is is appears in the alert box when the element is clicked.
msg = 'The value has changed.';
</script>
</body>
</html>

Frameworks such as YUI must do something similar with their automatic scope correction functionality.

Copyright James Gardner 1996-2020 All Rights Reserved. Admin.