web-dev-qa-db-fra.com

Comment puis-je remplacer la boîte de dialogue OnBeforeUnload et la remplacer par la mienne?

Je dois avertir les utilisateurs des modifications non enregistrées avant de quitter une page (problème assez courant).

window.onbeforeunload=handler

Cela fonctionne, mais une boîte de dialogue par défaut est déclenchée avec un message standard irritant qui enveloppe mon propre texte. Je dois soit remplacer complètement le message standard pour que mon texte soit clair, soit (mieux encore) remplacer l'intégralité du dialogue par un dialogue modal utilisant jQuery.

Jusqu'à présent, j'ai échoué et je n'ai trouvé personne d'autre qui semble avoir une réponse. Est-ce même possible?

Javascript dans ma page:

<script type="text/javascript">   
   window.onbeforeunload=closeIt;
</script>

La fonction closeIt ():

function closeIt()
{
  if (changes == "true" || files == "true")
  {
      return "Here you can append a custom message to the default dialog.";
  }
}

En utilisant jQuery et jqModal, j'ai essayé ce genre de chose (en utilisant un dialogue de confirmation personnalisé):

$(window).beforeunload(function() {
        confirm('new message: ' + this.href + ' !', this.href);
        return false;
    });

ce qui ne fonctionne pas non plus - je n'arrive pas à me lier à l'événement beforeunload.

337
flesh

Vous ne pouvez pas modifier le dialogue par défaut pour onbeforeunload, votre meilleur choix est donc de travailler avec.

window.onbeforeunload = function() {
    return 'You have unsaved changes!';
}

Voici une référence à cela de Microsoft:

Lorsqu'une chaîne est affectée à la propriété returnValue de window.event, une boîte de dialogue apparaît, offrant aux utilisateurs la possibilité de rester sur la page en cours et de conserver la chaîne qui lui a été affectée. L'instruction par défaut qui apparaît dans la boîte de dialogue, "Êtes-vous sûr de vouloir quitter cette page? ... Appuyez sur OK pour continuer ou sur Annuler pour rester sur la page en cours.", Ne peut pas être supprimé ou modifié.

Le problème semble être:

  1. Lorsque onbeforeunload est appelé, la valeur renvoyée par le gestionnaire est définie sous la forme window.event.returnValue.
  2. Il analysera ensuite la valeur de retour sous forme de chaîne (sauf si elle est null).
  3. Puisque false est analysé en tant que chaîne, la boîte de dialogue s'ouvre, ce qui permet ensuite de passer un true/false approprié.

Le résultat est qu'il ne semble pas y avoir de moyen d'assigner false à onbeforeunload pour l'empêcher d'entrer dans le dialogue par défaut.

Notes complémentaires sur jQuery:

  • Le paramétrage de l'événement dans jQuery peut être problématique , car cela permet à d'autres événements onbeforeunload de se produire. Si vous souhaitez uniquement que votre événement de déchargement se produise, tenez-vous-en à JavaScript.
  • jQuery n'a pas de raccourci pour onbeforeunload, vous devez donc utiliser la syntaxe générique bind.

    $(window).bind('beforeunload', function() {} );
    

Éditer 09/04/2018 : les messages personnalisés dans les boîtes de dialogue onbeforeunload sont obsolètes depuis chrome-51 (cf: note de version )

292
Owen

Ce qui a fonctionné pour moi avec jQuery et testé dans IE8, Chrome et Firefox, est la suivante:

$(window).bind("beforeunload",function(event) {
    if(hasChanged) return "You have unsaved changes";
});

Il est important de ne rien renvoyer si aucune invite n'est requise car il existe des différences entre IE et les autres comportements du navigateur.

27
grebe

Bien que vous ne puissiez rien faire à propos de la boîte dans certaines circonstances, vous pouvez intercepter quelqu'un qui clique sur un lien. Pour moi, cela valait la peine pour la plupart des scénarios et, en guise de secours, j'ai laissé l'événement de déchargement.

J'ai utilisé Boxy au lieu du dialogue standard jQuery, il est disponible ici: http://onehackoranother.com/projects/jquery/boxy/

$(':input').change(function() {
    if(!is_dirty){
        // When the user changes a field on this page, set our is_dirty flag.
        is_dirty = true;
    }
});

$('a').mousedown(function(e) {
    if(is_dirty) {
        // if the user navigates away from this page via an anchor link, 
        //    popup a new boxy confirmation.
        answer = Boxy.confirm("You have made some changes which you might want to save.");
    }
});

window.onbeforeunload = function() {
if((is_dirty)&&(!answer)){
            // call this if the box wasn't shown.
    return 'You have made some changes which you might want to save.';
    }
};

Vous pouvez attacher à un autre événement et filtrer davantage sur le type d'ancre sur lequel l'utilisateur a cliqué, mais cela fonctionne pour moi et ce que je veux faire et sert d'exemple pour que les autres utilisent ou améliorent. Je pensais partager cela pour ceux qui voulaient cette solution.

J'ai coupé le code, il est donc possible que cela ne fonctionne pas tel quel.

20
Dan Power

1) Utilisez onbeforeunload, pas onunload.

2) L'important est d'éviter l'exécution d'une déclaration de retour. Je ne veux pas dire par là éviter de revenir de votre gestionnaire. Vous revenez bien, mais vous le faites en veillant à atteindre la fin de la fonction et à NE PAS exécuter une instruction return. Dans ces conditions, la boîte de dialogue standard intégrée ne se produit pas.

3) Vous pouvez, si vous utilisez onbeforeunload, exécuter un appel ajax dans votre gestionnaire Unbeforeunload pour ranger le serveur, mais il doit être synchrone et vous devez attendre et traiter la réponse dans votre gestionnaire onbeforeunload (tout en respectant condition (2) ci-dessus). Je fais ça et ça marche bien. Si vous effectuez un appel ajax synchrone, tout est mis en attente jusqu'au retour de la réponse. Si vous en faites une asynchrone, pensant que vous ne vous souciez pas de la réponse du serveur, le déchargement de la page se poursuit et votre appel ajax est abandonné par ce processus, y compris un script distant s'il est en cours d'exécution.

9
user1164763

Cela ne peut pas être fait dans chrome maintenant pour éviter le spam, référez-vous à javascript onforforload ne montrant pas le message personnalisé pour plus de détails.

4
Abhijeet

Essayez de placer un return; au lieu d'un message .. cela fonctionne pour la plupart des navigateurs. (Cela empêche vraiment les cadeaux de dialogues)

window.onbeforeunload = function(evt) {            
        //Your Extra Code
        return;
}
4
Donald Powell

Je rencontrais le même problème, je pouvais obtenir sa propre boîte de dialogue avec mon message, mais le problème que je rencontrais était le suivant: 1) Il s'agissait de donner un message sur toutes les navigations, je le veux uniquement pour un clic rapproché. 2) avec mon propre message de confirmation si l'utilisateur sélectionne annuler, il affiche toujours la boîte de dialogue par défaut du navigateur.

Voici le code de solutions que j'ai trouvé, que j'ai écrit sur ma page maître.

function closeMe(evt) {
    if (typeof evt == 'undefined') {
        evt = window.event; }
    if (evt && evt.clientX >= (window.event.screenX - 150) &&
        evt.clientY >= -150 && evt.clientY <= 0) {
        return "Do you want to log out of your current session?";
    }
}
window.onbeforeunload = closeMe;
3
Imran Rizvi

Vous pouvez détecter le bouton (ok ou cancel) enfoncé par l'utilisateur, car la fonction onunload n'est appelée que lorsque l'utilisateur choisit de quitter la page. Bien que, dans cette fonction, les possibilités soient limitées, car le DOM est en train de s’effondrer. Vous pouvez exécuter javascript, mais le ajax POST ne fait rien et vous ne pouvez donc pas utiliser cette méthode pour la déconnexion automatique. Mais il existe une solution pour cela. Window.open ('logout.php') exécuté dans la fonction onunload afin que l'utilisateur se déconnecte avec une nouvelle fenêtre.

function onunload = (){
    window.open('logout.php');
}

Ce code appelé lorsque l'utilisateur quitte la page ou ferme la fenêtre active et que l'utilisateur est déconnecté par 'logout.php'. La nouvelle fenêtre se ferme immédiatement lorsque la déconnexion php se compose de code:

window.close();
3
Tamas Cseh
 <script type="text/javascript">
        window.onbeforeunload = function(evt) {
            var message = 'Are you sure you want to leave?';
            if (typeof evt == 'undefined') {
                evt = window.event;
            }       
            if (evt) {
                evt.returnValue = message;
            }
            return message;
        } 
    </script>

se référer de http://www.codeprojectdownload.com

1
Krishna Patel

Qu'en est-il d'utiliser la version spécialisée de la commande "bind" "one". Une fois que le gestionnaire d'événements est exécuté pour la première fois, il est automatiquement supprimé en tant que gestionnaire d'événements.

$(window).one("beforeunload", BeforeUnload);
1
Riga