Gestion des événements HTML dans AIR

Adobe AIR 1.0 et les versions ultérieures

Un système de gestion des événements permet au programmeur de répondre aux actions de l’utilisateur et aux événements système de manière pratique. Le modèle d’événement Adobe® AIR® n’est pas seulement utile, il est également conforme aux standards en vigueur. Ce modèle repose sur la spécification d’événements Document Object Model (DOM) de niveau 3, une architecture de gestion d’événements normalisée. Il constitue donc pour les programmeurs un outil puissant, mais parfaitement intuitif.

Evénements HTMLLoader

Un objet HTMLLoader déclenche les événements Adobe® ActionScript® 3.0 suivants :

Evénement

Description

htmlDOMInitialize

Distribué lors de la création du document HTML, mais avant que tout script soit analysé ou que les nœuds DOM soient ajoutés à la page.

complete

Distribué lors de la création du DOM HTML en réponse à une opération de chargement, juste après l’événement onload sur la page HTML.

htmlBoundsChanged

Distribué lorsque l’une des propriétés contentWidth et contentHeight ou les deux à la fois ont été modifiées.

locationChange

Distribué lorsque la propriété location de l’objet HTMLLoader a été modifiée.

locationChanging

Distribué avant que l’emplacement de l’objet HTMLLoader ne change suite à la navigation de l’utilisateur, à un appel de JavaScript ou à une redirection. L’événement locationChanging n’est pas distribué lorsque vous appelez la méthode load(), loadString(), reload(), historyGo(), historyForward() ou historyBack().

L’appel de la méthode preventDefault() de l’objet d’événement distribué annule la navigation.

Si un lien est ouvert dans le navigateur système, aucun événement locationChanging n’est distribué, car l’objet HTMLLoader ne change pas d’emplacement.

scroll

Distribué à chaque changement de position de défilement par le moteur HTML. Un événement scroll résulte d’un accès aux liens d’ancrage (liens #) sur la page ou d’un appel de la méthode window.scrollTo(). La saisie de texte dans une zone de texte ou d’entrée de texte peut également provoquer un événement scroll.

uncaughtScriptException

Distribué lorsqu’il se produit une exception JavaScript dans l’objet HTMLLoader et qu’elle n’est pas interceptée dans le code JavaScript.

Vous pouvez également associer une fonction ActionScript à un événement JavaScript (tel que onClick). Pour plus d’informations, voir la section Gestion des événements DOM avec ActionScript.

Gestion des événements DOM avec ActionScript

Vous pouvez enregistrer des fonctions ActionScript qui répondent à des événements JavaScript. Examinons par exemple le contenu HTML suivant :

<html> 
<body> 
    <a href="#" id="testLink">Click me.</a> 
</html>

Vous pouvez enregistrer une fonction ActionScript en tant que gestionnaire de tout événement de la page. Par exemple, le code suivant ajoute la fonction clickHandler() en tant qu’écouteur de l’événement onclick de l’élément testLink sur la page HTML :

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( event:Object ):void { 
    trace("Event of type: " + event.type ); 
}

L’objet événement distribué n’est pas de type flash.events.Event et n’appartient pas à l’une des sous-classes Event. La classe Object permet de déclarer le type de l’argument de la fonction du gestionnaire d’événement.

Vous pouvez également utiliser la méthode addEventListener() pour enregistrer des fonctions associées à ces événements. Il est par exemple possible de remplacer la méthode completeHandler() dans l’exemple précédent par le code suivant :

function completeHandler(event:Event):void { 
    var testLink:Object = html.window.document.getElementById("testLink"); 
    testLink.addEventListener("click", clickHandler); 
}

Lorsqu’un écouteur se réfère à un élément DOM déterminé, il est recommandé d’attendre que l’objet HTMLLoader parent distribue l’événement complete avant d’ajouter les écouteurs d’événement. Les pages HTML chargent souvent plusieurs fichiers et le DOM HTML n’est pas totalement généré tant que tous les fichiers n’ont pas été chargés et analysés. Une fois tous les éléments créés, l’objet HTMLLoader distribue l’événement complete.

Réponse aux exceptions JavaScript non interceptées

Examinez le code HTML suivant :

<html> 
<head> 
    <script> 
        function throwError() { 
            var x = 400 * melbaToast; 
        } 
    </script> 
</head> 
<body> 
    <a href="#" onclick="throwError()">Click me.</a> 
</html>

Il contient une fonction JavaScript, throwError(), qui fait référence à une variable inconnue, melbaToast :

var x = 400 * melbaToast;

Lorsqu’une opération JavaScript rencontre une opération non valide qui n’est pas interceptée dans le code JavaScript par une structure try/catch, l’objet HTMLLoader contenant la page distribue un événement HTMLUncaughtScriptExceptionEvent. Vous pouvez enregistrer un gestionnaire associé à cet événement, comme illustré par le code suivant :

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); 
    } 
}

JavaScript permet de gérer le même événement à l’aide de la propriété window.htmlLoader :

<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>

Le gestionnaire d’événement htmlErrorHandler() annule le comportement par défaut de l’événement (qui consiste à envoyer le message d’erreur JavaScript à la sortie de suivi AIR) et génère son propre message de sortie. Il stipule la valeur exceptionValue de l’objet HTMLUncaughtScriptExceptionEvent. Il indique par ailleurs les propriétés de chaque objet dans le tableau stackTrace :

exceptionValue: ReferenceError: Can't find variable: melbaToast 
sourceURL: app:/test.html 
line: 5 
function: throwError 
sourceURL: app:/test.html 
line: 10 
function: onclick

Gestion des événements d’exécution avec JavaScript

Les classes d’exécution gèrent l’ajout de gestionnaires d’événement à l’aide de la méthode addEventListener(). Pour ajouter une fonction de gestionnaire associée à un événement, appelez la méthode addEventListener() de l’objet qui distribue l’événement en indiquant le type d’événement et la fonction concernée. Par exemple, pour écouter l’événement closing distribué lorsqu’un utilisateur clique sur le bouton de fermeture de fenêtre dans la barre de titre, utilisez l’instruction suivante :

window.nativeWindow.addEventListener(air.NativeWindow.CLOSING, handleWindowClosing);

Création d’une fonction de gestionnaire d’événement

Le code suivant crée un fichier HTML simple qui affiche des informations sur la position de la fenêtre principale. Une fonction de gestionnaire appelée moveHandler() écoute un événement move (défini par la classe NativeWindowBoundsEvent) de la fenêtre principale.

<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>

Lorsqu’un utilisateur déplace la fenêtre, les éléments textarea affichent les positions X et Y actualisées de la fenêtre.

Notez que l’objet événement est transmis sous forme d’argument à la méthode moveHandler. Le paramètre d’événement permet à la fonction de gestionnaire d’examiner l’objet événement. Dans cet exemple, vous utilisez la propriété type de l’objet événement pour indiquer si cet événement est de type move.

Suppression des écouteurs d’événement

La méthode removeEventListener() permet de supprimer un écouteur d’événement dont vous n’avez plus besoin. Il est judicieux de supprimer tous les écouteurs qui ne seront plus utilisés. Les paramètres requis sont notamment eventName et listener, soit les mêmes que ceux requis pour la méthode addEventListener().

Suppression d’écouteurs d’événement sur une page HTML de navigation

Lorsqu’un contenu HTML navigue ou qu’il est éliminé parce qu’une fenêtre dans laquelle il figure est fermée, les écouteurs d’événement qui font référence aux objets sur la page déchargée ne sont pas automatiquement supprimés. Lorsqu’un objet distribue un événement à un gestionnaire qui a déjà été déchargé, le message d’erreur suivant s’affiche : « The application attempted to reference a JavaScript object in an HTML page that is no longer loaded » (L’application a tenté de référencer un objet JavaScript sur une page HTML qui n’est plus chargée).

Pour éviter que ce message d’erreur ne s’affiche, supprimez les écouteurs d’événement JavaScript intégrés à une page HTML avant qu’elle ne soit déchargée. En cas de navigation de page (au sein d’un objet HTMLLoader), supprimez l’écouteur d’événement lors de l’événement unload de l’objet window.

Par exemple, le code JavaScript suivant supprime un écouteur associé à un événement uncaughtScriptException :

window.onunload = cleanup; 
window.htmlLoader.addEventListener('uncaughtScriptException', uncaughtScriptException); 
function cleanup() 
{ 
    window.htmlLoader.removeEventListener('uncaughtScriptException', 
                            uncaughtScriptExceptionHandler); 
}

Pour empêcher que cette erreur ne se produise à la fermeture des fenêtres comportant un contenu HTML, appelez une fonction de nettoyage en réponse à l’événement closing de l’objet NativeWindow (window.nativeWindow). Par exemple, le code JavaScript suivant supprime un écouteur associé à un événement uncaughtScriptException :

window.nativeWindow.addEventListener(air.Event.CLOSING, cleanup); 
function cleanup() 
{ 
    window.htmlLoader.removeEventListener('uncaughtScriptException', 
                            uncaughtScriptExceptionHandler); 
}

Pour éviter que cette erreur ne se produise, vous pouvez également supprimer un écouteur d’événement dès son exécution (sous réserve que l’événement ne doive être géré qu’une seule fois). Par exemple, le code JavaScript suivant crée une fenêtre HTML en appelant la méthode createRootWindow() de la classe HTMLLoader et ajoute un écouteur associé à l’événement complete. Lorsque le gestionnaire d’événement complete est appelé, il supprime son propre écouteur d’événement par le biais de la fonction removeEventListener() :

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"));

La suppression d’écouteurs d’événement superflus permet également au nettoyeur de mémoire système de récupérer la mémoire éventuellement mobilisée par ces écouteurs.

Vérification des écouteurs d’événement existants

La méthode hasEventListener() vous permet de vérifier l’existence d’un écouteur d’événement associé à un objet.