2010-02-24 4 views
1

J'ai une application Flex qui permet à l'utilisateur de modifier un document basé sur un nuage. (Pensez SlideRocket.) Lorsque l'utilisateur essaie de naviguer ou de fermer la fenêtre du navigateur, je voudrais leur montrer une boîte de dialogue «êtes-vous sûr» si elles ont des modifications non enregistrées. J'utilise la classe personnalisée suivante, que j'ai trouvée à Flash player notified on browser close or change page (as3). Je ne pense pas c'est le problème.Demander confirmation à l'utilisateur avant la fermeture du navigateur _iff_ une variable Flex est vraie

package 
{ 
    import flash.external.ExternalInterface; 

    public class ExternalInterfaceUtil 
    { 
     public static function addExternalEventListener(qualifiedEventName:String, callback:Function, callBackAlias:String):void 
     { 
       // 1. Expose the callback function via the callBackAlias 
       ExternalInterface.addCallback(callBackAlias, callback); 

       // 2. Build javascript to execute 
       var jsExecuteCallBack:String = "document.getElementsByName('"+ExternalInterface.objectID+"')[0]."+callBackAlias+"()"; 
       var jsBindEvent:String = "function(){"+qualifiedEventName+"= function(){"+jsExecuteCallBack+"};}"; 

       // 3. Execute the composed javascript to perform the binding of the external event to the specified callBack function 
       ExternalInterface.call(jsBindEvent); 
     } 
    } 
} 

Dans ma fonction applicationComplete, j'ajouter un écouteur d'événement au javascript événement window.onbeforeunload, comme suit:

ExternalInterfaceUtil.addExternalEventListener("window.onbeforeunload", requestUnloadConfirmation, "unloadConfirmation"); 

La fonction Actionscript requestUnloadConfirmation (ci-dessous) est appelé avec succès lorsque l'utilisateur tente de ferme la fenêtre du navigateur. Cependant, cela n'empêche pas le navigateur de se fermer. (Dans Chrome, le navigateur se ferme et la fonction Actionscript est appelée par la suite. Dans Firefox, le navigateur reste ouvert pendant toute la durée de la fonction, mais se ferme alors.)

private function requestUnloadConfirmation():String { 
    if (changedSinceSave) 
     return "There are unsaved changes. Are you sure you want to leave without saving?"; 
    else 
     return null; 
} 

Le comportement est identique dans le débogage et la libération construit, et sur le serveur de production ainsi que sur la machine locale.

Toute aide serait grandement appréciée,

Dave

Répondre

2

À l'heure actuelle, lorsque l'événement JavaScript est déclenché, il est configuré pour appeler votre fonction dans votre code AS3, ce qu'il fait. Cependant, la fonction JavaScript ne renvoie pas la valeur renvoyée par votre fonction AS3. Pour obtenir ce comportement, ajouter « retour » à la fonction de gestion des événements JavaScript créé en addExternalEventListener comme ceci:

var jsBindEvent:String = "function(){"+qualifiedEventName+"= function(){return "+jsExecuteCallBack+"};}"; 

Depuis le gestionnaire d'événements doit renvoyer une valeur vraie ou fausse, votre fonction requestUnloadConfirmation doit avoir un type de retour Boolean et renvoyer false pour annuler l'événement, et true sinon. Utilisez ce qui suit pour obtenir une boîte de dialogue de confirmation:

private function requestUnloadConfirmation():Boolean {   
    if (changedSinceSave)   
     return ExternalInterface.call("confirm", "There are unsaved changes. Are you sure you want to leave without saving?"); 
    else   
     return false;   
} 

MISE À JOUR: Il se trouve que le retour d'une chaîne à window.onbeforeunload provoque une boîte de dialogue de confirmation à afficher automatiquement. ExternalInterface.call à confirmer provoque l'affichage d'une deuxième boîte de dialogue; c'est redondant. Le seul changement requis dans le code AS3 est d'ajouter le "retour" dans le JavaScript généré.

+0

Ajout d'un retour à la fonction de gestion des événements a fait l'affaire. Merci mille fois pour avoir sauvé la journée! Pour ceux d'entre vous qui liront ceci dans le futur: Le changement proposé à requestUnloadConfirmation n'était pas nécessaire - et, en fait, conduit à deux boîtes de dialogue de confirmation qui sont montrées successivement plutôt que juste une. En effet, renvoyer une valeur de chaîne à window.onbeforeunload provoque l'affichage d'une boîte de dialogue de confirmation. Vous n'avez pas besoin de demander explicitement un autre. Testé comme fonctionnant dans Chrome, Firefox, Safari. Je suppose que cela fonctionne dans IE comme Microsoft a inventé window.onbeforeunload dans IE4. –

+0

Oh, cool! Je ne savais pas à propos de la confirmation automatique lors du retour d'une chaîne dans windows.onbeforeunload. Je n'ai joué qu'une seule fois avec cet événement, pour le plaisir. Je vais modifier ma réponse. – Cameron

+0

Désolé, ce code n'est pas complet et ne fonctionnera pas bien, j'ai posté les corrections ci-dessous – Uri

0

Dans un html régulier/javascript web-app vous pouvez utiliser l'événement window.onbeforeunload pour ce faire.

http://www.4guysfromrolla.com/demos/OnBeforeUnloadDemo1.htm

Peut-être que vous pouvez utiliser cet événement, et vérifier une valeur de votre application flexible pour déterminer si vous devez demander à l'utilisateur (pas familier avec flex ...)?

0

J'ai dû exécuter quelques modifications dans le code ci-dessus pour le faire fonctionner. Le problème était dû au fait que la fonction qui gère la fenêtre d'événement.onbeforeunload, ne devrait pas retourner une valeur pour éviter la confirmation de pop-up et doit retourner la valeur de texte lors de la confirmation de pop-up est en ordre

Voici mes changements:

private function requestUnloadConfirmation():String {   
      if (changedSinceSave){ 
        return "There are unsaved changes. Are you sure you want to leave without saving?"; 
      } 
      return null;   
     } 

Et un peu de changement dans eMbedded JS

var jsBindEvent:String = "function(){"+qualifiedEventName+"= function(){ if ("+jsExecuteCallBack+") return "+jsExecuteCallBack+"};}"; 
Questions connexes