Empêcher la navigation d'une page Web à l'aide de JavaScript


129

Comment empêcher une page Web de s'éloigner en utilisant JavaScript?


Qu'est-ce qui fait que cette page s'éloigne?
Niyaz

9
Selon la question, JavaScript le fait naviguer loin ...
Shog9


@ Shog9, il se peut que la fermeture de l'onglet le fasse naviguer. My index finger did tha ...
Bob Stein

Réponses:


159

L'utilisation onunloadvous permet d'afficher des messages, mais n'interrompt pas la navigation (car il est trop tard). Cependant, l'utilisation onbeforeunloadinterrompra la navigation:

window.onbeforeunload = function() {
  return "";
}

Remarque: Une chaîne vide est renvoyée car les navigateurs plus récents fournissent un message tel que "Toutes les modifications non enregistrées seront perdues" qui ne peut pas être remplacé.

Dans les anciens navigateurs, vous pouviez spécifier le message à afficher dans l'invite:

window.onbeforeunload = function() {
  return "Are you sure you want to navigate away?";
}

11
Le navigateur affichera une invite appropriée. Simplement utiliserwindow.onbeforeunload = function() { return ""; }
KIM Taegyoon

Mais cela ne suffit pas. Qu'en est-il des contrôles à l'intérieur du formulaire? Ils déclenchent cela aussi.
Fandango68

1
Les navigateurs modernes ne vous permettent pas d'afficher un message personnalisé dans l'invite, car cela a été abusé par des hameçonneurs et autres.
Flimm

Merci @Flimm, j'ai mis à jour la réponse afin qu'elle soit maintenant précise pour les navigateurs actuels.
Jimmie R. Houts

@FlimmJe souhaite mettre à jour le statut de l'utilisateur en ligne lorsque les utilisateurs en ligne ferment l'onglet du navigateur ou le navigateur.J'ai utilisé le code dans la solution mais cela n'a pas fonctionné.Y a-t-il une solution pour cela?
Nasimba

23

Contrairement aux autres méthodes présentées ici, ce bit de code ne fera pas afficher au navigateur un avertissement demandant à l'utilisateur s'il veut partir; au lieu de cela, il exploite la nature événementielle du DOM pour rediriger vers la page actuelle (et donc annuler la navigation) avant que le navigateur n'ait une chance de la décharger de la mémoire.

Comme il fonctionne en court-circuitant directement la navigation, il ne peut pas être utilisé pour empêcher la fermeture de la page; cependant, il peut être utilisé pour désactiver le contournement d'images.

(function () {
    var location = window.document.location;

    var preventNavigation = function () {
        var originalHashValue = location.hash;

        window.setTimeout(function () {
            location.hash = 'preventNavigation' + ~~ (9999 * Math.random());
            location.hash = originalHashValue;
        }, 0);
    };

    window.addEventListener('beforeunload', preventNavigation, false);
    window.addEventListener('unload', preventNavigation, false);
})();

Avertissement: vous ne devriez jamais faire cela. Si une page contient du code de contournement de cadre, veuillez respecter les souhaits de l'auteur.


comment afficher modal si l'utilisateur veut fermer le navigateur (cliquez sur fermer)? vraiment?

15

J'ai fini avec cette version légèrement différente:

var dirty = false;
window.onbeforeunload = function() {
    return dirty ? "If you leave this page you will lose your unsaved changes." : null;
}

Ailleurs, je règle le drapeau sale sur true lorsque le formulaire est sali (ou je veux autrement empêcher la navigation). Cela me permet de contrôler facilement si l'utilisateur reçoit ou non l'invite Confirmer la navigation.

Avec le texte de la réponse sélectionnée, vous voyez des invites redondantes:

entrez la description de l'image ici


3
Dans IE, si dirty est false, une chaîne «null» sera affichée. Enveloppez-le simplement dans une instruction if. Voir: stackoverflow.com/questions/11793996/…
Jacob van Lingen

D'accord @JacobvanLingen, ce serait la meilleure réponse ici et sur trois autres questions si elle se terminait par au undefinedlieu de null. (1) c'est conditionnel (2) il mentionne "sale" la raison légitime la plus courante pour empêcher la navigation et (3) il a une capture d'écran.
Bob Stein

Cela fonctionnerait-il sur tous les navigateurs s'il se terminait par undefined plutôt que null?
Danger

9

L'équivalent d'une manière plus moderne et compatible avec les navigateurs, en utilisant les API addEventListener modernes.

window.addEventListener('beforeunload', (event) => {
  // Cancel the event as stated by the standard.
  event.preventDefault();
  // Chrome requires returnValue to be set.
  event.returnValue = '';
});

Source: https://developer.mozilla.org/en-US/docs/Web/Events/beforeunload


1
N'oubliez pas de capitaliser correctementevent.returnValue
Flimm

7

Dans l'exemple d'Ayman, en retournant false, vous empêchez la fenêtre / l'onglet du navigateur de se fermer.

window.onunload = function () {
  alert('You are trying to leave.');
  return false;
}

2
Sauf si le navigateur est Opera, qui ignore l'événement onunload si l'onglet / la fenêtre / le programme est en cours de fermeture.
Powerlord

5

L'équivalent de la réponse acceptée dans jQuery 1.11:

$(window).on("beforeunload", function () {
    return "Please don't leave me!";
});

Exemple JSFiddle

La réponse de altCognito a utilisé l' unloadévénement, ce qui arrive trop tard pour que JavaScript abandonne la navigation.


3

Utilisez onunload .

Pour jQuery, je pense que cela fonctionne comme ceci:

$(window).unload(function() { 
  alert("Unloading"); 
  return falseIfYouWantToButBeCareful();
});

Renvoyer false n'annulera malheureusement pas le déchargement - l' unloadévénement se déclenche lorsque l'utilisateur quitte la page, contrairement à beforeunloadce qui se déclenche juste avant (et peut être annulé)
Jimbo

@altCognito: Vous m'avez donné une bonne idée avec falseIfYouWantToButBeCareful () Maintenant, je peux éviter le pop-up par défaut donné par IE ou FF. Mais pour le chrome, cela ne fonctionne pas. Regardant dedans.
user367134

3

Ce message d'erreur suggéré peut dupliquer le message d'erreur que le navigateur affiche déjà. Dans Chrome, les 2 messages d'erreur similaires s'affichent l'un après l'autre dans la même fenêtre.

Dans Chrome, le texte affiché après le message personnalisé est: "Êtes-vous sûr de vouloir quitter cette page?". Dans Firefox, il n'affiche pas du tout notre message d'erreur personnalisé (mais affiche toujours la boîte de dialogue).

Un message d'erreur plus approprié pourrait être:

window.onbeforeunload = function() {
    return "If you leave this page, you will lose any unsaved changes.";
}

Ou style stackoverflow: "Vous avez commencé à écrire ou modifier un article."


2

Si vous attrapez un bouton Précédent / Suivant du navigateur et que vous ne voulez pas vous en éloigner, vous pouvez utiliser:

window.addEventListener('popstate', function() {
    if (window.location.origin !== 'http://example.com') {
        // Do something if not your domain
    } else if (window.location.href === 'http://example.com/sign-in/step-1') {
        window.history.go(2); // Skip the already-signed-in pages if the forward button was clicked
    } else if (window.location.href === 'http://example.com/sign-in/step-2') {
        window.history.go(-2); // Skip the already-signed-in pages if the back button was clicked
    } else {
        // Let it do its thing
    }
});

Sinon, vous pouvez utiliser l' événement beforeunload , mais le message peut ou non fonctionner dans plusieurs navigateurs et nécessite le renvoi de quelque chose qui force une invite intégrée.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.