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

je dois prévenir les utilisateurs des changements non sauvegardés avant qu'ils ne quittent une page (un problème assez courant).

window.onbeforeunload=handler

cela fonctionne, mais il soulève un dialogue par défaut avec un message standard irritant qui enveloppe mon propre texte. J'ai besoin soit de remplacer complètement le message standard, de sorte que mon texte est clair, ou (encore mieux) remplacer l'ensemble de la boîte de dialogue par une boîte de dialogue modale en utilisant jQuery.

Jusqu'à présent j'ai échoué et je n'ai trouvé personne d'autre qui semble avoir une réponse. Est-il 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;
    });

qui aussi ne fonctionne pas - Je ne peux pas sembler lier à l'événement beforeunload.

319
demandé sur Danil Speransky 2008-11-10 02:24:17

12 réponses

vous ne pouvez pas modifier le dialogue par défaut pour onbeforeunload , ainsi votre meilleur pari peut être de travailler avec elle.

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

Voici une référence de Microsoft:

Lorsqu'une chaîne de caractères est assignée à la propriété returnValue de window.event, une boîte de dialogue apparaît qui donne aux utilisateurs la possibilité de rester sur la page courante et de conserver la chaîne qui leur a été assignée. La déclaration par défaut que s'affiche dans la boîte de dialogue "voulez-vous vraiment quitter cette page? ... Appuyez sur OK POUR CONTINUER, ou Annuler pour rester sur la page courante."ne peut pas être supprimé ou modifié.

Le problème semble être:

  1. quand onbeforeunload est appelé, il prendra la valeur de retour du handler comme window.event.returnValue .
  2. il analysera alors la valeur de retour en chaîne (à moins qu'elle ne soit nulle).
  3. étant donné que false est interprété comme une chaîne, la boîte de dialogue va tirer, qui passera alors un true / false approprié .

le résultat est, il ne semble pas y avoir une façon d'attribuer false à onbeforeunload pour l'empêcher du dialogue par défaut.

Notes complémentaires sur jQuery:

  • fixer l'événement dans jQuery peut être problématique, comme cela permet à d'autres onbeforeunload événements de se produire aussi bien. Si vous souhaitez seulement que votre événement de déchargement se produise, Je m'en tiens au bon vieux JavaScript.
  • jQuery n'a pas de raccourci pour onbeforeunload donc vous devez utiliser la syntaxe générique bind .

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

Edit 09/04/2018 : les messages personnalisés dans les boîtes de dialogue onbeforeunload sont dépréciés depuis chrome-51 (cf.: release note )

285
répondu Owen 2018-04-09 16:53:36

Owen a raison. Et, la raison derrière ceci est la sécurité. Empêcher une page de se décharger est utile dans les formulaires web et autres, mais il peut facilement être exploité par un site malveillant pour tromper l'utilisateur à rester sur une page. C'est pourquoi les navigateurs web implémentent le message standard et disposent de ce mécanisme pour insérer du texte personnalisé.

42
répondu pluckyglen 2009-04-22 19:47:27

ce qui a fonctionné pour moi, en utilisant jQuery et testé dans IE8, Chrome et Firefox, est:

$(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 y a des différences entre IE et les autres comportements du navigateur ici.

27
répondu grebe 2018-07-18 19:28:16

bien qu'il n'y ait rien que vous puissiez faire à propos de la boîte dans certaines circonstances, vous pouvez intercepter quelqu'un en cliquant sur un lien. Pour moi, cela valait la peine pour la plupart des scénarios et comme solution de rechange, j'ai quitté l'événement de déchargement.

j'ai utilisé Boxy à la place de la boîte de 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.';
    }
};

que vous pourriez attacher à un autre événement, et filtre plus sur ce genre d'ancre a été cliqué, mais cela fonctionne pour moi et ce que je veux faire et sert d'exemple pour les autres à utiliser ou à améliorer. J'ai pensé que je partagerais ceci pour ceux qui veulent Cette solution.

j'ai découpé le code, donc cela ne peut pas fonctionner tel quel.

18
répondu Dan Power 2012-07-12 04:48:47

1) utiliser onbeforeunload, not onunload.

2) l'important est d'éviter d'exécuter une déclaration de retour. Je ne veux pas, par là, éviter de revenir de votre contact. Vous retournez tout droit, mais vous le faites en vous assurant que vous atteignez la fin de la fonction et N'exécutez pas une instruction de retour. Dans ces conditions, le dialogue standard intégré ne se produit pas.

3) Vous pouvez, si vous utilisez onbeforeunload, lancer un appel ajax dans votre unbeforeunload handler pour ranger sur le serveur, mais il doit être synchrone, et vous devez attendre et gérer la réponse dans votre onbeforeunload handler (respectant toujours la condition (2) ci-dessus). Je le fais et cela fonctionne très bien. Si tu fais un appel ajax synchrone, tout est maintenu jusqu'à la réponse. Si vous faites une réponse asynchrone, pensant que vous ne vous souciez pas de la réponse du serveur, le déchargement de la page continue et votre appel ajax est avorté par ce processus - y compris un script distant si il tourne.

9
répondu user1164763 2012-09-18 20:48:19

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

window.onbeforeunload = function(evt) {            
        //Your Extra Code
        return;
}
4
répondu Donald Powell 2013-03-16 09:58:46

vous pouvez détecter quel bouton (ok ou cancel) appuyé par l'utilisateur, parce que la fonction onunload appelé seulement lorsque l'utilisateur choisit de quitter la page. Bien que dans cette fonction les possibilités soient limitées, parce que le DOM est en train de s'effondrer. Vous pouvez lancer javascript, mais l'ajax POST ne fait rien donc vous ne pouvez pas utiliser cette méthode pour la déconnexion automatique. Mais il y a une solution pour cela. Fenêtre.open('logout.php') exécuté dans le funcion onunload, donc l'utilisateur se déconnectera avec une nouvelle ouverture de la fenêtre.

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

ce code s'appelle lorsque l'utilisateur quitte la page ou ferme la fenêtre active et que l'utilisateur se déconnecte par 'déconnexion.php". La nouvelle fenêtre se ferme immédiatement lorsque php logout se compose de code:

window.close();
3
répondu Tamas Cseh 2012-03-04 09:43:18

j'ai fait face au même problème, j'étais ok pour obtenir sa propre boîte de dialogue avec mon message, mais le problème que j'ai rencontré était : 1) il donnait le message sur toutes les navigations je le veux seulement pour le clic étroit. 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 des solutions que j'ai trouvé, que j'ai écrit sur ma page principale.

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
répondu Imran Rizvi 2013-10-04 12:39:31

cela ne peut pas être fait dans chrome maintenant pour éviter le spamming, se référer à javascript onbeforeunload ne montrant le message personnalisé pour plus de détails.

3
répondu Abhijeet 2017-05-31 00:39:30
 <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>

reportez-vous à partir de http://www.codeprojectdownload.com

1
répondu Krishna Patel 2012-03-16 10:11:24

j'ai eu ce même problème et ça me rendait fou. Je voulais me débarrasser complètement de la pop-up parce que je ne voulais pas avertir l'utilisateur -- il suffit de les prendre d'un formulaire à une nouvelle page. J'ai essayé les réponses ci-dessus et je n'ai pas pu en obtenir.

finalement, j'ai eu ceci pour ignorer le popup par défaut de firefox, avec l'aide de ce site: http://code-maven.com/prevent-leaving-the-page-using-plain-javascript . Il est ajouté avant que vous redirigiez la fenêtre:

window.onbeforeunload = function() {
    if (data_needs_saving()) {
         return "";
    } else {
         return "";
    }
};
window.location.href = 'www.redirect here';
1
répondu imapotatoe123 2016-08-09 17:27:48

Qu'en est-il de la version spécialisée de la commande" bind ""one". Une fois que le gestionnaire d'événement exécute la première fois, il est automatiquement supprimé comme un gestionnaire d'événement.

$(window).one("beforeunload", BeforeUnload);
0
répondu Riga 2017-06-26 05:22:08