A única maneira de realmente fazer isso (e é como a 'história realmente simples' faz isso) é definindo um intervalo que continua verificando o hash atual e comparando-o com o que era antes, fazemos isso e permitimos que os assinantes assinem uma alteração evento que disparamos se o hash mudar .. não é perfeito, mas os navegadores realmente não suportam esse evento nativamente.
Atualize para manter esta resposta atualizada:
Se você estiver usando o jQuery (que hoje deve ser um pouco fundamental para a maioria), uma boa solução é usar a abstração que o jQuery fornecer, usando seu sistema de eventos para ouvir eventos de alteração de hash no objeto da janela.
$(window).on('hashchange', function() {
//.. work ..
});
O bom aqui é que você pode escrever um código que nem precisa se preocupar com o suporte à mudança de hash, no entanto, você precisa fazer alguma mágica, na forma de um recurso jQuery um pouco menos conhecido, eventos especiais do jQuery .
Com esse recurso, você basicamente executa algum código de configuração para qualquer evento, a primeira vez que alguém tenta usar o evento de qualquer maneira (como vincular ao evento).
Nesse código de configuração, você pode verificar o suporte nativo ao navegador e, se o navegador não implementar isso nativamente, você pode configurar um cronômetro único para pesquisar alterações e acionar o evento jQuery.
Isso desvincula completamente seu código da necessidade de entender esse problema de suporte; a implementação de um evento especial desse tipo é trivial (para obter uma versão funcional simples de 98%), mas por que fazer isso quando outra pessoa já o fez .