Impedir que uma página da Web navegue para longe usando JavaScript


129

Como impedir que uma página da Web navegue para longe usando JavaScript?


O que faz com que esta página navegue?
Niyaz 04/05/09

9
De acordo com a questão, JavaScript torna navegar longe ...
Shog9


@ Shog9, pode estar fechando a aba, fazendo com que ela se afaste. Meu dedo indicador ...
Bob Stein

Respostas:


159

O uso onunloadpermite exibir mensagens, mas não interrompe a navegação (porque é tarde demais). No entanto, o uso onbeforeunloadinterromperá a navegação:

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

Nota: Uma cadeia vazia é retornada porque os navegadores mais recentes fornecem uma mensagem como "Quaisquer alterações não salvas serão perdidas" que não podem ser substituídas.

Em navegadores mais antigos, você pode especificar a mensagem a ser exibida no prompt:

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

11
O navegador exibirá um prompt apropriado. Simplesmente usewindow.onbeforeunload = function() { return ""; }
KIM Taegyoon

Mas isso não basta. E quanto aos controles dentro do formulário? Eles também desencadeiam isso.
Fandango68

1
Navegadores modernos não permitem que você exiba uma mensagem personalizada no prompt, pois isso foi abusado por phishers e similares.
Flimm

Obrigado @Flimm, atualizei a resposta para que agora seja precisa nos navegadores atuais.
Jimmie R. Houts

@FlimmEu quero atualizar o status online do usuário quando os usuários online fecham a guia ou o navegador. Usei o código na solução, mas ele não funcionou. Existe uma solução para isso?
Nasimba 29/03

23

Ao contrário de outros métodos apresentados aqui, esse trecho de código não fará com que o navegador exiba um aviso perguntando ao usuário se ele deseja sair; em vez disso, explora a natureza do evento do DOM para redirecionar de volta à página atual (e, assim, cancelar a navegação) antes que o navegador possa descarregá-lo da memória.

Como ele funciona com um curto-circuito direto na navegação, não pode ser usado para impedir que a página seja fechada; no entanto, ele pode ser usado para desativar o bloqueio de quadros.

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

Isenção de responsabilidade: você nunca deve fazer isso. Se uma página tiver um código de quebra de quadros, respeite os desejos do autor.


como show modal se o usuário quiser fechar o navegador (clique em fechar)? é mesmo?

15

Acabei com esta versão um pouco diferente:

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

Em outros lugares, defino o sinalizador sujo como verdadeiro quando o formulário fica sujo (ou, caso contrário, desejo impedir a navegação). Isso me permite controlar facilmente se o usuário recebe ou não o prompt Confirmar Navegação.

Com o texto na resposta selecionada, você verá avisos redundantes:

insira a descrição da imagem aqui


3
No IE, se sujo for falso, uma string 'null' será mostrada. Apenas envolva-o dentro de uma instrução if. Veja: stackoverflow.com/questions/11793996/…
Jacob van Lingen

Concordou em @JacobvanLingen, essa seria a melhor resposta aqui e em outras três perguntas se terminasse em vez de nulo. (1) é condicional (2) menciona "sujo" o motivo legítimo mais comum para impedir a navegação e (3) possui uma captura de tela. undefined
Bob Stein

Isso funcionaria em todos os navegadores se terminasse com indefinido em vez de nulo?
Danger


7

No exemplo de Ayman, retornando false, você impede que a janela / guia do navegador se feche.

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

2
A menos que o navegador seja o Opera, que ignora o evento onunload se a guia / janela / programa estiver sendo fechada.
Powerlord

5

O equivalente à resposta aceita no jQuery 1.11:

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

Exemplo JSFiddle

A resposta de altCognito usou o unloadevento, que acontece muito tarde para o JavaScript abortar a navegação.


3

Use onunload .

Para jQuery, acho que funciona assim:

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

Retornando falsa não vai cancelar o descarregamento infelizmente - os unloadincêndios de evento quando o usuário é sair da página, ao contrário do beforeunloadque dispara apenas de antemão (e pode ser cancelada)
Jimbo

@altCognito: Você me deu uma boa idéia com falseIfYouWantToButBeCareful () Agora, posso evitar o pop-up padrão fornecido pelo IE ou FF. Mas, para o chrome, não está funcionando. Olhando para isso.
user367134

3

Essa mensagem de erro sugerida pode duplicar a mensagem de erro que o navegador já exibe. No chrome, as duas mensagens de erro semelhantes são exibidas uma após a outra na mesma janela.

No chrome, o texto exibido após a mensagem personalizada é: "Tem certeza de que deseja sair desta página?". No firefox, ele não exibe nossa mensagem de erro personalizada (mas ainda exibe a caixa de diálogo).

Uma mensagem de erro mais apropriada pode ser:

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

Ou no estilo stackoverflow: "Você começou a escrever ou editar uma postagem."


2

Se você estiver pegando o botão voltar / avançar do navegador e não quiser sair, pode usar:

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

Caso contrário, você pode usar o evento beforeunload , mas a mensagem pode ou não funcionar em vários navegadores e requer a devolução de algo que força um prompt interno.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.