Mudanças noNavigateEvent no Chrome 105

Joe Medley
Joe Medley

O Chrome 105 apresenta dois novos métodos no NavigateEvent da API Navigation (lançada na versão 102) para melhorar métodos que se mostraram problemáticos na prática. O intercept(), que permite que os desenvolvedores controlem o estado após a navegação, substitui o transitionWhile(), que se mostrou difícil de usar. O método scroll(), que rola até uma âncora especificada no URL, substitui restoreScroll(), que não funciona para todos os tipos de navegação.

Neste artigo, explicarei os problemas com ambos e como os novos métodos corrigem esses problemas.

O método NavigateEvent.trasitionWhile(), introduzido com a API Navigation no Chrome 102, intercepta a navegação para transições do lado do cliente em apps de página única. O primeiro argumento é uma promessa que sinaliza ao navegador e a outras partes do aplicativo da Web que ele foi concluído.

Na prática, isso não funcionou. Considere este padrão de programação comum:

event.transitionWhile((async () => {
  doSyncStuff();
  await doAsyncStuff();
})());

Isso é funcionalmente equivalente ao código abaixo. Isso faz com que parte da navegação seja executada antes que a API saiba que o desenvolvedor pretende interceptar a navegação.

doSyncStuff();
event.transitionWhile((async () => {
  await doAsyncStuff();
})());

Um exemplo em que isso pode atrapalhar um app é na lógica de restauração de rolagem, em que ela captura posições de rolagem após a mudança do DOM, em vez de antes.

O que mudou

Para substituir transitionWhile(), a especificação atual introduz NavigateEvent.intercept(). O novo método usa um gerenciador além das propriedades focusReset e scrollRestoration aceitas por transitionWhile(). O novo gerenciador sempre é executado após a confirmação da navegação e itens como posições de rolagem foram capturadas, evitando os problemas com transitionWhile().

O método transitionWhile() ainda está disponível, mas foi descontinuado e será removido no Chrome 108.

Como usar intercept()

O NavigateEvent.intercept() tem as mesmas restrições que transitionWhile(), já que não pode ser chamado em todos os eventos de navegação. As navegações entre origens não podem ser interceptadas, assim como as transições entre documentos. Isso vai gerar uma DOMException do tipo "SecurityError".

Para usar intercept(), basta transmitir seu gerenciador personalizado ao fazer a chamada.

navigation.addEventListener("navigate", event => {
  event.intercept({
    async handler() {
      doSyncStuff();
      await doAsyncStuff();
    }
  });
});

Uma navegação, como a da parte de cima da página para uma âncora (chamada de movimento de /a para /a#id), é processada completamente pelo navegador, mesmo em um app de página única. No entanto, a navegação para uma âncora em outra "página" (/a para /b#id), que é simples para apps de várias páginas, é mais complicada para apps de página única. O app precisa interceptar a navegação para /b#id usando NavigateEvent.transitionWhile() e, em seguida, chamar NavigateEvent.restoreScroll() para exibir a âncora. Como mencionado acima, isso é difícil de fazer no momento.

O que mudou

Em apps de página única, agora é possível controlar se o navegador lida com a rolagem para uma âncora ou se o código faz isso.

Como usar scroll()

Por padrão, o navegador vai tentar processar a rolagem automaticamente quando o manipulador de interceptação for atendido. Se você quiser lidar com a rolagem, defina scroll como "manual" e chame NavigateEvent.scroll() quando o navegador tentar definir a posição de rolagem.

navigation.addEventListener("manual", event => {
  scroll: "manual",
  event.intercept({
    async handler() {
      doSyncStuff();
      // Handle scrolling earlier than by default:
      event.scroll();
      await doAsyncStuff();
    }
  });
});

O método restoreScroll() ainda está disponível, mas foi descontinuado e será removido no Chrome 108.

Conclusão

Esperamos atualizar em breve nosso artigo sobre a API Navigation. Enquanto isso, a especificação da API contém muitas informações especificamente para desenvolvedores da Web.

Foto de Tim Gouw no Unsplash