Lidar com evento de mudança de âncora de URL em js

Respostas:

126

Os Mecanismos de pesquisa personalizados do Google usam um cronômetro para verificar o hash em relação a um valor anterior, enquanto o iframe filho em um domínio separado atualiza o hash de localização do pai para conter o tamanho do corpo do documento do iframe. Quando o cronômetro detecta a alteração, o pai pode redimensionar o iframe para corresponder ao do corpo, de forma que as barras de rolagem não sejam exibidas.

Algo como o seguinte atinge o mesmo:

var storedHash = window.location.hash;
window.setInterval(function () {
    if (window.location.hash != storedHash) {
        storedHash = window.location.hash;
        hashChanged(storedHash);
    }
}, 100); // Google uses 100ms intervals I think, might be lower

Google Chrome 5, Safari 5, Opera 10.60 , Firefox 3.6 e Internet Explorer 8 todo o apoio do hashchangeevento:

if ("onhashchange" in window) // does the browser support the hashchange event?
    window.onhashchange = function () {
        hashChanged(window.location.hash);
    }

e juntando tudo:

if ("onhashchange" in window) { // event supported?
    window.onhashchange = function () {
        hashChanged(window.location.hash);
    }
}
else { // event not supported:
    var storedHash = window.location.hash;
    window.setInterval(function () {
        if (window.location.hash != storedHash) {
            storedHash = window.location.hash;
            hashChanged(storedHash);
        }
    }, 100);
}

jQuery também tem um plugin que irá verificar o evento hashchange e fornecer o seu próprio, se necessário - http://benalman.com/projects/jquery-hashchange-plugin/ .

EDIT : Atualizado suporte do navegador (novamente).

Andy E
fonte
para completar, adicione var storedHash = window.location.hash;ao bloco de resumo de junção. Btw: Hoje em dia isso é chamado de polyfill, eu acho.
Frank Nocke,
1
Hoje em dia você pode ouvir hashChangeem window stackoverflow.com/questions/6390341/how-to-detect-url-change
Timo Huovinen
@AndyE Eu li a resposta, perdi a pequena nota e nunca vi eventos que se pareçam comhashChanged(storedHash);
Timo Huovinen,
1
@TimoHuovinen:, hashChangedneste caso, pretende ser uma função implementada por um desenvolvedor usando este código. A resposta aqui apenas demonstra como é possível monitorar o hash em busca de alterações onde o onhashchangeevento não está disponível e combina as abordagens baseadas em eventos e temporizadas para fornecer uma solução universal. Meu ponto é que a resposta que você vinculou não adiciona absolutamente nada à resposta aqui ;-). Eles fornecem as mesmas informações básicas, até mesmo o link para o plugin jQuery de Ben Alman. A única diferença é que forneci uma solução JS pura em minha resposta.
Andy E
1
Eu estava procurando um roteador JS leve, mas ele fez o trabalho muito bem. Também eliminou todas as dependências :)
gskema
3

Eu recomendaria usar em addEventListenervez de substituir window.onhashchange, caso contrário, você bloqueará o evento para outros plug-ins.

window.addEventListener('hashchange', function() {
...
})

Olhando para o uso global do navegador hoje, um fallback não é mais necessário.

Fabian von Ellerts
fonte
2

Pelo que vejo em outras perguntas do SO, a única solução viável entre navegadores é um cronômetro. Confira esta pergunta por exemplo.

Pekka
fonte
1

(Apenas para registro.) O evento sintético "hashchange" YUI3 faz mais ou menos a mesma coisa que a resposta aceita

YUI().use('history-hash', function (Y) {
  Y.on('hashchange', function (e) {
    // Handle hashchange events on the current window.
  }, Y.config.win);
});
mjhm
fonte
0

Você pode obter mais informações deste

Tipos de evento de mutação

O módulo de evento de mutação é projetado para permitir a notificação de qualquer alteração na estrutura de um documento, incluindo modificações de atributo e de texto.

Rahul
fonte
Trata-se de mudanças no DOM.
Raj de