An event-handling system allows programmers to respond to user input and system events in a convenient way. The AIR runtime classes event model is not only convenient, but also standards-compliant. Based on the Document Object Model (DOM) Level 3 Events Specification, an industry-standard event-handling architecture, the event model provides a powerful, yet intuitive, event-handling tool for programmers.
An HTMLLoader object dispatches the following ActionScript events:
|
Event |
Description |
|---|---|
|
htmlDOMInitialize |
Dispatched when the HTML document is created, but before any scripts are parsed or DOM nodes are added to the page. |
|
complete |
Dispatched when the HTML DOM has been created in response to a load operation, immediately after the onload event in the HTML page. |
|
htmlBoundsChanged |
Dispatched when one or both of the contentWidth and contentHeight properties have changed. |
|
locationChange |
Dispatched when the location property of the HTMLLoader has changed. |
|
scroll |
Dispatched anytime the HTML engine changes the scroll position. Scroll events can be because of navigation to anchor links (# links) in the page or because of calls to the window.scrollTo() method. Entering text in a text input or text area can also cause a scroll event. |
|
uncaughtScriptException |
Dispatched when a JavaScript exception occurs in the HTMLLoader and the exception is not caught in JavaScript code. |
You can also register an ActionScript function for a JavaScript event (such as onClick). For details, see Handling DOM events with ActionScript.
You can register ActionScript functions to respond to JavaScript events. For example, consider the following HTML content:
<html>
<body>
<a href="#" id="testLink">Click me.</a>
</html>
You can register an ActionScript function as a handler for any event in the page. For example, the following code adds the clickHandler() function as the listener for the onclick event of the testLink element in the HTML page:
var html:HTMLLoader = new HTMLLoader( );
var urlReq:URLRequest = new URLRequest("test.html");
html.load(urlReq);
html.addEventListener(Event.COMPLETE, completeHandler);
function completeHandler(event:Event):void {
html.window.document.getElementById("testLink").onclick = clickHandler;
}
function clickHandler():void {
trace("You clicked it!");
}
You can also use the addEventListener() method to register for these events. For example, you could replace the completeHandler() method in the previous example with the following code:
function completeHandler(event:Event):void {
var testLink:Object = html.window.document.getElementById("testLink");
testLink.addEventListener("click", clickHandler);
}
When a listener refers to a specific DOM element, it is good practice to wait for the parent HTMLLoader to dispatch the complete event before adding the event listeners. HTML pages often load multiple files and the HTML DOM is not fully built until all the files are loaded and parsed. The HTMLLoader dispatches the complete event when all elements have been created.
Consider the following HTML:
<html>
<head>
<script>
function throwError() {
var x = 400 * melbaToast;
}
</script>
</head>
<body>
<a href="#" onclick="throwError()">Click me.</a>
</html>
It contains a JavaScript function, throwError(), that references an unknown variable, melbaToast:
var x = 400 * melbaToast;
When a JavaScript operation encounters an illegal operation that is not caught in the JavaScript code with a try/catch structure, the HTMLLoader object containing the page dispatches an HTMLUncaughtScriptExceptionEvent event. You can register a handler for this event, as in the following code:
var html:HTMLLoader = new HTMLLoader();
var urlReq:URLRequest = new URLRequest("test.html");
html.load(urlReq);
html.width = container.width;
html.height = container.height;
container.addChild(html);
html.addEventListener(HTMLUncaughtScriptExceptionEvent.UNCAUGHT_SCRIPT_EXCEPTION,
htmlErrorHandler);
function htmlErrorHandler(event:HTMLUncaughtJavaScriptExceptionEvent):void
{
event.preventDefault();
trace("exceptionValue:", event.exceptionValue)
for (var i:int = 0; i < event.stackTrace.length; i++)
{
trace("sourceURL:", event.stackTrace[i].sourceURL);
trace("line:", event.stackTrace[i].line);
trace("function:", event.stackTrace[i].functionName);
}
}
Within JavaScript, you can handle the same event using the window.htmlLoader property:
<html>
<head>
<script language="javascript" type="text/javascript" src="AIRAliases.js"></script>
<script>
function throwError() {
var x = 400 * melbaToast;
}
function htmlErrorHandler(event) {
event.preventDefault();
var message = "exceptionValue:" + event.exceptionValue + "\n";
for (var i = 0; i < event.stackTrace.length; i++){
message += "sourceURL:" + event.stackTrace[i].sourceURL +"\n";
message += "line:" + event.stackTrace[i].line +"\n";
message += "function:" + event.stackTrace[i].functionName + "\n";
}
alert(message);
}
window.htmlLoader.addEventListener("uncaughtScriptException", htmlErrorHandler);
</script>
</head>
<body>
<a href="#" onclick="throwError()">Click me.</a>
</html>
The htmlErrorHandler() event handler cancels the default behavior of the event (which is to send the JavaScript error message to the AIR trace output), and generates its own output message. It outputs the value of the exceptionValue of the HTMLUncaughtScriptExceptionEvent object. It outputs the properties of each object in the stackTrace array:
exceptionValue: ReferenceError: Can't find variable: melbaToast sourceURL: app:/test.html line: 5 function: throwError sourceURL: app:/test.html line: 10 function: onclick
The AIR runtime classes support adding event handlers with the addEventListener() method. To add a handler function for an event, call the addEventListener() method of the object that dispatches the event, providing the event type and the handling function. For example, to listen for the closing event dispatched when a user clicks the window close button on the title bar, use the following statement:
window.nativeWindow.addEventListener(air.NativeWindow.CLOSING, handleWindowClosing);
The following code creates a simple HTML file that displays information about the position of the main window. A handler function named moveHandler(), listens for a move event (defined by the NativeWindowBoundsEvent class) of the main window.
<html>
<script src="AIRAliases.js" />
<script>
function init() {
writeValues();
window.nativeWindow.addEventListener(air.NativeWindowBoundsEvent.MOVE,
moveHandler);
}
function writeValues() {
document.getElementById("xText").value = window.nativeWindow.x;
document.getElementById("yText").value = window.nativeWindow.y;
}
function moveHandler(event) {
air.trace(event.type); // move
writeValues();
}
</script>
<body onload="init()" />
<table>
<tr>
<td>Window X:</td>
<td><textarea id="xText"></textarea></td>
</tr>
<tr>
<td>Window Y:</td>
<td><textarea id="yText"></textarea></td>
</tr>
</table>
</body>
</html>
When a user moves the window, the textarea elements display the updated X and Y positions of the window:
Notice that the event object is passed as an argument to the moveHandler() method. The event parameter allows your handler function to examine the event object. In this example, you use the event object's type property to report that the event is a move event.
When HTML content navigates, or when HTML content is discarded because a window that contains it is closed, the event listeners that reference objects on the unloaded page are not automatically removed. When an object dispatches an event to a handler that has already been unloaded, you will see the following error message: "The application attempted to reference a JavaScript object in an HTML page that is no longer loaded."
To avoid this error, remove JavaScript event listeners in an HTML page before it goes away. In the case of page navigation (within an HTMLLoader object), remove the event listener during the unload event of the window object.
For example, the following JavaScript code removes an event listener for an uncaughtScriptException event:
window.onunload = cleanup;
window.htmlLoader.addEventListener('uncaughtScriptException', uncaughtScriptException);
function cleanup()
{
window.htmlLoader.removeEventListener('uncaughtScriptException',
uncaughtScriptExceptionHandler);
}
To prevent the error from occurring when closing windows that contain HTML content, call a cleanup function in response to the closing event of the NativeWindow object (window.nativeWindow). For example, the following JavaScript code removes an event listener for an uncaughtScriptException event:
window.nativeWindow.addEventListener(air.Event.CLOSING, cleanup);
function cleanup()
{
window.htmlLoader.removeEventListener('uncaughtScriptException',
uncaughtScriptExceptionHandler);
}
You can also prevent this error from occurring by removing an event listener as soon as it runs. For example, the following JavaScript code creates an html window by calling the createRootWindow() method of the HTMLLoader class and adds an event listener for the complete event. When the complete event handler is called, it removes its own event listener using the removeEventListener() function:
var html = runtime.flash.html.HTMLLoader.createRootWindow(true);
html.addEventListener('complete', htmlCompleteListener);
function htmlCompleteListener()
{
html.removeEventListener(complete, arguments.callee)
// handler code..
}
html.load(new runtime.flash.net.URLRequest("second.html"));
Removing unneeded event listeners also allows the system garbage collector to reclaim any memory associated with those listeners.