SwiftHTML & CSSSolidityDesenvolvimento de JogosSolana/Rust
17.12.2024

Resolvendo o problema com history.replaceState() no Chrome

Resposta Rápida

Para modificar a URL no navegador e o estado correspondente sem precisar atualizar a página e criar uma nova entrada no histórico do navegador, use o método history.replaceState(). Esse método é ideal para navegação AJAX em aplicações de página única.

Como Funciona:

// A URL muda para "pagina-atualizada.html", mas a página não é recarregada
history.replaceState({ detalhe: 'atualização' }, '', 'pagina-atualizada.html');

Essência: A URL é atualizada para pagina-atualizada.html, e todo o conteúdo da página permanece inalterado. O objeto de estado ({ detalhe: 'atualização' }) é usado para acompanhar as mudanças dentro da página da web atual.

É importante lembrar que history.replaceState() não afeta o título do documento. Para mudá-lo, você precisa definir separadamente o valor de document.title:

Exemplo de atualização do título:

// Agora vamos renomear o título
document.title = 'Título da Página Atualizada';
history.replaceState({ detalhe: 'atualização' }, 'Título da Página Atualizada', 'pagina-atualizada.html');

Navegação pelo Histórico do Navegador

Cada navegador tem suas características peculiares, e nem sempre lidam corretamente com o parâmetro title para replaceState() e pushState(). Compreender melhor essas nuances levará algum tempo.

Sobrevivendo às Diferenças entre Navegadores

Teste seu código em todos os navegadores populares antes do lançamento do projeto para evitar surpresas desagradáveis. Lembre-se de que o comportamento de replaceState() pode variar entre diferentes navegadores, como Chrome ou Opera.

Mudando o Título do Documento

Ao mudar o título do documento, faça assim:

// Shhh, não estamos aqui
document.getElementsByTagName('title')[0].innerHTML = 'novo título';

Acompanhando Mudanças de Navegação

Use o evento window.onpopstate para rastrear mudanças na navegação do histórico do navegador:

// Ah, alguém pressionou o botão "voltar"?
window.onpopstate = function(event) {
  if (event.state) {
    atualizarConteudo(event.state.detalhe);
  }
};

function atualizarConteudo(detalhe) {
  // Lógica para atualizar o conteúdo vai aqui
}

Superando Obstáculos com AJAX

replaceState() em combinação com AJAX permite que você busque e exiba novo conteúdo sem fazer o usuário esperar o recarregamento da página.

// Hora de surpreender o usuário com novo conteúdo
function carregarConteudo(url) {
  // Buscar o conteúdo e atualizar a URL sem recarregar a página
  fetch(url)
    .then(response => response.text())
    .then(html => {
      document.getElementById('conteudo').innerHTML = html;
      history.replaceState({ conteudo: html }, '', url);
    });
}

Se você estiver usando jQuery, isso simplifica o gerenciamento de conteúdo AJAX e a interação com pushState e popstate.

Visualização

Imagine history.replaceState() como um assistente inteligente 🕵️‍♂️ que muda a trama de um livro sem levantar suspeitas:

Antes de usar ReplaceState: 📖 [Página 1 - Introdução, Página 2 - Desenvolvimento da Trama, Página 3 - Clímax]

Aqui vem nosso assistente esperto:

history.replaceState({pagina: 2}, "Título", "/pagina-2");

Após aplicar o ReplaceState: 📖 [Página 1 - Introdução, Página 2 - Reviravolta Estonteante!, Página 3 - Clímax]

Ninguém suspeitará que nada mudou; a história continua fluindo como antes.

Recursos Úteis

  1. Método History: replaceState() - Web API | MDN — descrição abrangente do método replaceState().
  2. Utilizando a API de Histórico do HTML5 | CSS-Tricks — guia para trabalhar com a API de Histórico do HTML5.
  3. GitHub - devote/HTML5-History-API — aprimorando a compatibilidade da API de Histórico em navegadores que não a suportam nativamente.
  4. javascript - Como mudar a URL sem recarregar a página? - Stack Overflow — discussões no Stack Overflow sobre como mudar a URL sem recarregar a página.
  5. Âncoras de Cabeçalho Markdown no GitHub · GitHub — uso prático de history.replaceState().

Video

Did you like this article? Rate it from 1 to 5:

Thank you for voting!