Pergunta

Eu preciso alertar os usuários sobre alterações não salvas antes de deixar uma página (um problema muito comum).

window.onbeforeunload=handler

Este funciona, mas ele levanta uma caixa de diálogo padrão com uma mensagem padrão irritante que envolve meu próprio texto. Eu preciso substituir completamente a mensagem padrão, por isso o meu texto é claro, ou (melhor ainda) substituir o diálogo inteira com um diálogo modal usando jQuery.

Até agora eu falhei e eu não encontrei qualquer outra pessoa que parece ter uma resposta. Será que é mesmo possível?

Javascript na minha página:

<script type="text/javascript">   
   window.onbeforeunload=closeIt;
</script>

O closeIt () função:

function closeIt()
{
  if (changes == "true" || files == "true")
  {
      return "Here you can append a custom message to the default dialog.";
  }
}

Usando jQuery e jqModal Tentei este tipo de coisa (usando um diálogo de confirmação personalizada):

$(window).beforeunload(function() {
        confirm('new message: ' + this.href + ' !', this.href);
        return false;
    });

que também não funciona - Eu não consigo vincular ao evento beforeunload.

Foi útil?

Solução

Você não pode modificar o diálogo padrão para onbeforeunload, então sua melhor aposta pode ser a de trabalhar com ele.

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

Aqui está uma referência ao presente da Microsoft :

Quando uma string é atribuído à propriedade returnValue de window.event, irá aparecer uma janela de caixa que dá aos usuários a opção de permanecer na página atual e manter a cadeia que foi atribuído a ele. A declaração padrão que aparece na caixa de diálogo, "Tem certeza de que deseja sair desta página? ... Pressione OK para continuar ou Cancelar para permanecer na página atual.", Não pode ser removido ou alterado.

O problema parece ser:

  1. Quando onbeforeunload é chamado, ele terá o valor de retorno do manipulador como window.event.returnValue.
  2. Será, então, analisar o valor de retorno como uma string (a menos que seja nulo).
  3. Uma vez que false é analisado como uma string, a caixa de diálogo irá disparar, o que irá, em seguida, passar um true apropriada / false.

O resultado é, não parece ser uma maneira de atribuir false para onbeforeunload para evitar que o diálogo padrão.

Notas adicionais sobre jQuery:

  • Definir o evento em jQuery pode ser problemático, como que permite que outros eventos onbeforeunload a ocorrer também. Se você quiser apenas para seu evento descarregar a ocorrer eu furar a simples ol' JavaScript para ele.
  • jQuery não tem um atalho para onbeforeunload assim que você teria que usar a sintaxe bind genérico.

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

Editar 2018/09/04 : mensagens personalizadas em diálogos onbeforeunload são obsoletas desde o cromo-51 (cf: liberação nota )

Outras dicas

O que funcionou para mim, usando jQuery e testado no IE8, Chrome e Firefox, é:

$(window).bind("beforeunload",function(event) {
    if(hasChanged) return "You have unsaved changes";
});

É importante não retornar nada se nenhum prompt é necessária uma vez que existem diferenças entre IE e outros comportamentos do navegador aqui.

Enquanto não há nada que você possa fazer sobre a caixa em algumas circunstâncias, você pode interceptar alguém clicar em um link. Para mim, este foi vale o esforço para a maioria dos cenários e como um fallback, eu deixei o evento unload.

Eu usei Boxy vez do jQuery diálogo padrão, ele está disponível aqui: 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.';
    }
};

Você pode anexar a um outro evento, e filtro mais sobre o tipo de âncora foi clicado, mas isso funciona para mim e que eu quero fazer e serve de exemplo para os outros para usar ou melhorar. Pensei que eu iria compartilhar isso para aqueles que querem esta solução.

Eu cortei código, de modo que este pode não funcionar como é.

1) Use OnBeforeUnload, não onunload.

2) O importante é evitar a execução de uma instrução de retorno. Não quero dizer, com isso, para evitar o retorno do seu manipulador. Devolver tudo certo, mas você fazê-lo, garantindo que você chegar ao final da função e não executar uma instrução de retorno. Nestas condições, o built-in de diálogo padrão não ocorre.

3) Você pode, se você usar onbeforeunload, executar uma chamada de ajax no seu manipulador unbeforeunload para arrumar no servidor, mas deve ser um síncrono, e você tem que esperar e lidar com a resposta no seu manipulador de onbeforeunload (continuando a respeitar a condição (2) acima). Eu faço isso e ele funciona muito bem. Se você fizer uma chamada ajax síncrono, tudo é mantido até que a resposta vem de volta. Se você fizer uma uma assíncrona, o pensamento de que você não se preocupam com a resposta do servidor, o descarregamento página continua e sua chamada ajax é abortada por este processo -. Incluindo um script remoto se ele estiver sendo executado

Tente colocar um return; em vez de uma mensagem .. isso está funcionando a maioria dos navegadores para mim. (Isso só realmente impede presentes de diálogo)

window.onbeforeunload = function(evt) {            
        //Your Extra Code
        return;
}

Você pode detectar qual botão (OK ou Cancelar) pressionado pelo usuário, porque a função onunload chamado somente quando a escolha do usuário leaveing ??página. Althoug neste funcion as possibilidades é limitada, porque o DOM está a ser recolhido. Você pode executar javascript, mas o ajax POST não fazer nada, portanto, você não pode usar este methode para a desconexão automática. Mas há uma solução para isso. O window.open ( 'logout.php') executado no funcion onunload, para que o usuário será desconectado com uma nova abertura da janela.

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

Este código de chamada quando o usuário deixar a página ou fechar a janela ativa e usuário logado por 'logout.php'. A nova janela perto imediatamente quando o logout php consistem em código:

window.close();

I enfrentou o mesmo problema, eu estava ok para obter a sua própria caixa de diálogo com a minha mensagem, mas o problema que eu enfrentei foi: 1) Foi dando mensagem em todas as navegações eu quero-o apenas para próximo clique. 2) com a minha própria mensagem de confirmação se o usuário seleciona cancelá-lo ainda mostra a caixa de diálogo padrão do navegador.

A seguir é o código de soluções que encontrei, que eu escrevi na minha página principal.

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;

Isto não pode ser feito em cromo agora a spam evitar, consulte javascript onbeforeunload não mostrando mensagem personalizada para mais detalhes.

 <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>

http://www.codeprojectdownload.com

Que tal usar a versão especializada do "bind" "um" comando. Uma vez que o manipulador de eventos é executado pela primeira vez, ele é removido automaticamente como um manipulador de eventos.

$(window).one("beforeunload", BeforeUnload);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top