Impedisci che una pagina web si allontani tramite JavaScript


129

Come impedire che una pagina web vada via usando JavaScript?


Cosa rende questa pagina lontana?
Niyaz,

9
Secondo la domanda, JavaScript lo fa andare via ...
Shog9


@ Shog9 potrebbe essere la chiusura della scheda lo fa allontanare. Il mio dito indice fece ...
Bob Stein, il

Risposte:


159

L'utilizzo onunloadconsente di visualizzare i messaggi, ma non interromperà la navigazione (perché è troppo tardi). Tuttavia, l'utilizzo onbeforeunloadinterromperà la navigazione:

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

Nota: viene restituita una stringa vuota perché i browser più recenti forniscono un messaggio come "Eventuali modifiche non salvate andranno perse" che non possono essere sostituite.

Nei browser meno recenti è possibile specificare il messaggio da visualizzare nel prompt:

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

11
Il browser visualizzerà un prompt appropriato. Basta usarewindow.onbeforeunload = function() { return ""; }
KIM Taegyoon il

Ma questo non è abbastanza. Che dire dei controlli all'interno del modulo? Innescano anche questo.
Fandango68

1
I browser moderni non consentono di visualizzare un messaggio personalizzato nel prompt, poiché questo è stato abusato da phisher e simili.
Flimm,

Grazie @Flimm, ho aggiornato la risposta in modo che ora sia accurata per i browser correnti.
Jimmie R. Houts,

@FlimmVoglio aggiornare lo stato online dell'utente quando gli utenti online chiudono la scheda o il browser del browser. Ho usato il codice nella soluzione ma non ha funzionato. C'è una soluzione per questo?
Nasimba

23

A differenza di altri metodi presentati qui, questo bit di codice non farà apparire un avviso al browser che chiede all'utente se vuole andarsene; invece, sfrutta la natura evented del DOM per reindirizzare alla pagina corrente (e quindi annullare la navigazione) prima che il browser abbia la possibilità di scaricarlo dalla memoria.

Poiché funziona cortocircuitando direttamente la navigazione, non può essere utilizzato per impedire la chiusura della pagina; tuttavia, può essere utilizzato per disabilitare il frame-busting.

(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);
})();

Disclaimer: non dovresti mai farlo. Se su una pagina è presente un codice di frame-busting, rispetta i desideri dell'autore.


come mostra modale se l'utente desidera chiudere il browser (fare clic su Chiudi)? veramente?

15

Ho finito con questa versione leggermente diversa:

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

Altrove ho impostato la bandiera sporca su true quando il modulo viene sporcato (o altrimenti desidero impedire la navigazione via). Ciò mi consente di controllare facilmente se l'utente riceve o meno il messaggio Conferma navigazione.

Con il testo nella risposta selezionata vengono visualizzati prompt ridondanti:

inserisci qui la descrizione dell'immagine


3
In IE se dirty è falso, verrà mostrata una stringa 'null'. Basta avvolgerlo in un'istruzione if. Vedi: stackoverflow.com/questions/11793996/…
Jacob van Lingen,

Concordato su @JacobvanLingen, questa sarebbe la migliore risposta qui e su altre tre domande se finisse invece che nulla. (1) è condizionale (2) menziona "sporco" il motivo legale più comune per impedire la navigazione e (3) ha uno screenshot. undefined
Bob Stein,

Funzionerebbe su tutti i browser se terminasse con indefinito anziché null?
Pericolo,

9

L'equivalente in un modo più moderno e compatibile con il browser, utilizzando le moderne API addEventListener.

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

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


1
Ricorda di capitalizzare correttamenteevent.returnValue
Flimm il

7

Nell'esempio di Ayman, restituendo false si impedisce la chiusura della finestra / scheda del browser.

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

2
A meno che il browser non sia Opera, che salta l'evento onunload se la scheda / finestra / programma viene chiusa.
Powerlord,

5

L'equivalente alla risposta accettata in jQuery 1.11:

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

JS Esempio di violino

La risposta di altCognito ha utilizzato l' unloadevento, che accade troppo tardi perché JavaScript interrompa la navigazione.


3

Usa onunload .

Per jQuery, penso che funzioni così:

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

La restituzione di falso non annullerà sfortunatamente lo scaricamento: l' unloadevento si attiva quando l'utente lascia la pagina, diversamente da quello beforeunloadche si attiva prima (e può essere annullato)
Jimbo,

@altCognito: Mi hai dato una buona idea con falseIfYouWantToButBeCareful () Ora posso evitare il pop-up predefinito fornito da IE o FF. Ma per Chrome non funziona. Guardandoci dentro.
user367134

3

Il messaggio di errore suggerito può duplicare il messaggio di errore già visualizzato nel browser. In Chrome, i 2 messaggi di errore simili vengono visualizzati uno dopo l'altro nella stessa finestra.

In Chrome, il testo visualizzato dopo il messaggio personalizzato è: "Sei sicuro di voler lasciare questa pagina?". In Firefox, non mostra affatto il nostro messaggio di errore personalizzato (ma mostra comunque la finestra di dialogo).

Un messaggio di errore più appropriato potrebbe essere:

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

O stile stackoverflow: "Hai iniziato a scrivere o modificare un post."


2

Se stai rilevando un pulsante Indietro / Avanti del browser e non desideri spostarti, puoi utilizzare:

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
    }
});

Altrimenti, è possibile utilizzare l' evento beforeunload , ma il messaggio potrebbe non funzionare su più browser e richiede la restituzione di qualcosa che forza un prompt incorporato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.