121 votes

Intercepter l'événement de sortie de la page

Lorsqu'il modifie une page dans mon système, un utilisateur peut décider de naviguer vers un autre site web et, ce faisant, perdre toutes les modifications qu'il n'a pas sauvegardées.

J'aimerais intercepter toute tentative d'aller sur une autre page et demander à l'utilisateur de s'assurer qu'il veut que cela se produise, car il pourrait potentiellement perdre son travail en cours.

Gmail procède de manière très similaire. Par exemple, composez un nouvel e-mail, commencez à taper dans le corps du message et saisissez un nouvel emplacement dans la barre d'adresse (disons twitter.com ou autre). Le système vous demandera "Êtes-vous sûr ?".

Des idées pour reproduire cela ? Je vise IE8, mais j'aimerais être compatible avec Firefox et Chrome également.

7 votes

0 votes

157voto

Eli Grey Points 17553

Similaire à la réponse de Ghommey, mais cette solution prend également en charge les anciennes versions d'IE et de Firefox.

window.onbeforeunload = function (e) {
  var message = "Your confirmation message goes here.",
  e = e || window.event;
  // For IE and Firefox
  if (e) {
    e.returnValue = message;
  }

  // For Safari
  return message;
};

1 votes

Pourriez-vous expliquer la première ligne (var message = ...) ? Je ne sais pas ce que font la virgule et la deuxième expression.

7 votes

@mtmurdock C'est juste la syntaxe Javascript pour déclarer des variables multiples. var foo, bar; est la même chose que var foo; var bar;

4 votes

@mtmurdock, La deuxième déclaration " var e = e || window.event ;" signifie mettre en place e égale au paramètre e (si c'est vrai) ou window.event si ce n'est pas vrai. Elle ne sera pas véridique si le paramètre e est nulle.

26voto

jantimon Points 12753

Voir cet article. La fonction que vous recherchez est la onbeforeunload

exemple de code :

  <script language="JavaScript">
  window.onbeforeunload = confirmExit;
  function confirmExit()
  {
    return "You have attempted to leave this page.  If you have made any changes to the fields without clicking the Save button, your changes will be lost.  Are you sure you want to exit this page?";
  }
</script>

2 votes

Existe-t-il un moyen d'identifier que l'utilisateur a choisi l'option "Quitter cette page" plutôt que "Rester sur cette page" ?

0 votes

@ShilpaSoni vous auriez bientôt un événement de déchargement ultérieur, developer.mozilla.org/fr/US/docs/Web/API/Window/unload_event mais je ne pense pas qu'il y ait un moyen synchrone.

6voto

Remi Points 4223

Au lieu d'une popup de confirmation ennuyeuse, il serait agréable de retardement du départ juste un peu (quelques millisecondes) pour réussir à poster les données non sauvegardées sur le serveur, ce que j'ai réussi à faire pour mon site en écrivant un texte factice dans la console comme ceci :

window.onbeforeunload=function(e){
  // only take action (iterate) if my SCHEDULED_REQUEST object contains data        
  for (var key in SCHEDULED_REQUEST){   
    postRequest(SCHEDULED_REQUEST); // post and empty SCHEDULED_REQUEST object
    for (var i=0;i<1000;i++){
      // do something unnoticable but time consuming like writing a lot to console
      console.log('buying some time to finish saving data'); 
    };
    break;
  };
}; // no return string --> user will leave as normal but data is send to server

Editar: Voir aussi Synchronous_AJAX et comment le faire avec jquery

0 votes

J'aime cette alternative au popup. Merci pour la suggestion, Remi.

2 votes

Cela n'a absolument aucun sens -1. javascript n'est pas threadé ce que vous faites c'est faire un postRequest et ensuite mettre en pause le calcul du site sans permettre à personne de ne rien faire (y compris votre postRequest, qui entre temps a déjà été envoyé avant la pause du calcul).

0 votes

Et c'est exactement pour cela que cela fonctionne : en effet, la post-requête a été envoyée avant la pause de calcul, mais ce petit blocage de la page avant qu'elle ne soit effectivement quittée assure suffisamment de temps pour que le client du navigateur (et non le javascript) finisse vraiment d'envoyer cette requête correctement. J'ai remarqué que lorsque je n'envoie que la requête (sans blocage) et que je quitte la page immédiatement après, la requête n'est pas toujours envoyée.

0voto

gordon Points 259

J'ai des utilisateurs qui n'ont pas rempli toutes les données requises.

<cfset unloadCheck=0>//a ColdFusion precheck in my page generation to see if unload check is needed
var erMsg="";
$(document).ready(function(){
<cfif q.myData eq "">
    <cfset unloadCheck=1>
    $("#myInput").change(function(){
        verify(); //function elsewhere that checks all fields and populates erMsg with error messages for any fail(s)
        if(erMsg=="") window.onbeforeunload = null; //all OK so let them pass
        else window.onbeforeunload = confirmExit(); //borrowed from Jantimon above;
    });
});
<cfif unloadCheck><!--- if any are outstanding, set the error message and the unload alert --->
    verify();
    window.onbeforeunload = confirmExit;
    function confirmExit() {return "Data is incomplete for this Case:"+erMsg;}
</cfif>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X