O Chrome 105 apresenta dois novos métodos na NavigateEvent
da API Navigation (introduzida na 102) para melhorar os métodos que apresentaram problemas 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, vou explicar os problemas com os dois e como os novos métodos corrigem esses problemas.
NavigateEvent.transitionWhile()
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.
Isso não funcionou bem na prática. 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, e não 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 navegação ser confirmada, e elementos como posições de rolagem são capturados, evitando 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();
}
});
});
NavigateEvent.scroll()
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 mostrar 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.