Recuperar a posição do scroll

Na PLP ao clicar em um produto ele redirecionar para a página de produto PDP, porém ao clicar no botão voltar do navegador a posição do scroll da página de coleção é perdida, voltando para o topo. Criei um componente que fixa a posição do scroll mas observei que os produtos são carregados conforme é feito o scroll na página, gerando diferenças na posição. Outro problema é que se utilizado a paginação durante o carregamento na PLP o carregamento dos produtos são contínuos, exibindo todos os produtos, porém se for para a PDP e voltar para a página, são retornando somente a quantidade máxima de produtos para aquela página:
Exemplos: o limite de produtos são 20, usando a paginação fica 60 produtos em uma página, ao ir para a PDP e voltar, retorna somente os 20 produtos referente aquela paginação. Alguém já passou por isso?

@fabiano.dev Tudo certo?

Esse problema é bastante comum em páginas de listagem de produtos (PLP) com carregamento dinâmico infinito e paginação. O comportamento de perder a posição do scroll e o número correto de produtos ao voltar da PDP pode ser causado por alguns fatores, como o comportamento padrão do navegador e o gerenciamento do estado da página.

Soluções possíveis para lidar com o problema:

  1. Armazenar a Posição do Scroll:
  • O componente que você criou para armazenar a posição do scroll é um passo importante, mas certifique-se de armazenar essa posição em um local que não se perca ao navegar para a PDP e voltar, como o localStorage ou o sessionStorage.

  • No retorno à PLP, você pode restaurar a posição do scroll manualmente após o carregamento completo dos produtos.

    Exemplo possível:

    window.addEventListener('beforeunload', () => {
      localStorage.setItem('scrollPosition', window.scrollY);
    });
    
    window.addEventListener('load', () => {
      const scrollPosition = localStorage.getItem('scrollPosition');
      if (scrollPosition) {
        window.scrollTo(0, parseInt(scrollPosition, 10));
      }
    });
    
  1. Gerenciar a Paginação Corretamente:
  • O comportamento que você descreveu, onde a página carrega um número maior de produtos ao fazer scroll (como 60), mas ao voltar da PDP exibe apenas os 20 produtos padrão, ocorre porque a PLP está sendo re-renderizada com base nos dados padrão ao invés do estado anterior da navegação. Para resolver isso, você pode armazenar o estado da página (incluindo o número de produtos carregados e a página atual) antes de navegar para a PDP. Isso pode ser feito com o localStorage ou sessionStorage.

Exemplo possível:

// Armazenar o estado da página antes de ir para PDP
const state = {
  productsLoaded: [...document.querySelectorAll('.product-item')].length,
  currentPage: currentPaginationPage
};
localStorage.setItem('plpState', JSON.stringify(state));

// Recuperar o estado ao voltar
const savedState = JSON.parse(localStorage.getItem('plpState'));
if (savedState) {
  loadProducts(savedState.productsLoaded);
  setCurrentPage(savedState.currentPage);
}
  1. Evitar o Recarregamento Completo da Página:
  • Quando o usuário volta para a PLP, a página está recarregando e refazendo as requisições para carregar os produtos. O ideal seria evitar o recarregamento completo da página ao navegar entre PDP e PLP, utilizando algo como o React Router ou AJAX para carregar as PDPs dinamicamente, mantendo o estado da PLP intacto.
  1. Infinite Scroll com Paginação Contínua:
  • Para corrigir o comportamento onde os produtos carregados na PLP são resetados ao voltar da PDP, você pode garantir que o componente de scroll infinito continue a carregar os produtos a partir da página onde o usuário parou, e não recomeçar a partir do zero.
  • Uma solução para isso seria usar um observer ou trigger para verificar quando os produtos precisam ser carregados, garantindo que o estado da paginação seja mantido e re-carregado corretamente.
  1. Persistir o Estado no Servidor:
  • Outra abordagem mais robusta seria persistir o estado da navegação e da paginação no servidor ou no backend da aplicação, de forma que mesmo que o usuário saia da PLP, os produtos carregados, a página atual e o scroll sejam mantidos de forma sincronizada entre cliente e servidor.

Observações:

Essas soluções variam em complexidade, dependendo de como a sua PLP é gerada e estruturada. Armazenar a posição do scroll e o estado da paginação no localStorage ou sessionStorage é a abordagem mais simples e eficaz para a maioria dos casos. Já o uso de React ou de AJAX pode ser necessário para uma navegação mais fluida entre as páginas.

Outra coisa importante é usar customizações. A VTEX claramente não dá suporte para componentes custom. Portanto, você precisa assumir que está seguindo as melhores práticas do mercado para não ter dores de cabeça no futuro numa possível manutenção ou adaptação do código.

Espero que essas informações possam te ajudar a encontrar um caminho de solução. Se for positivo, marque-a como solução para apoiar outros da comunidade.

Abs,
Estevão.

2 Likes

@estevao_santos, obrigado mais uma vez pela contribuição!

Essa situação é algo que outros devs apresentaram pra VTEX conforme aqui nessa issue, estou usando as páginas de categorias e coleções nativas da VTEX, sobre o armazenamento da posição do scroll funciona sem paginação, porém conforme eu vou paginando quando eu clico em um produto e vou para a PDP e clico em voltar, em alguns momentos a página é carregada com os produtos somente a partir da última paginação acessada. Segue um vídeo em anexo simulando no store theme da VTEX. Vou continuar tentando aqui, pois o cliente insiste nisso :expressionless:.

1 Like

@fabiano.dev Por nada!

Entendi. Pode ser algo que realmente não tenha uma solução viável. Daí eu sinalizaria para o cliente que isso é uma limitação e não tem muito o que fazer. Fora que se fizer algo talvez não fique 100% e o pode ter mais problemas do que mantido do jeito que está.

Você já tentou combinar 2 ideias: armazenar o estado da página + realizar o scroll até o produto selecionado.

Isso tudo usando localstorage.

Veja se isso funciona:

Captura do estado da página e realização do scroll ao retornar da PDP:

// Armazenar a posição do scroll e o estado da página antes de ir para a PDP
window.addEventListener('beforeunload', () => {
  const state = {
    scrollPosition: window.scrollY,
    currentPage: currentPaginationPage,  // Salvar a página atual da paginação
    productsLoaded: [...document.querySelectorAll('.product-item')].length
  };
  localStorage.setItem('plpState', JSON.stringify(state));
});

// Recuperar a posição do scroll e o estado ao voltar para a PLP
window.addEventListener('load', () => {
  const savedState = JSON.parse(localStorage.getItem('plpState'));
  if (savedState) {
    // Restaura o número da página da paginação e produtos carregados
    setCurrentPage(savedState.currentPage);  
    loadProducts(savedState.productsLoaded); 

    // Após carregar os produtos, restaura a posição do scroll
    window.scrollTo(0, parseInt(savedState.scrollPosition, 10));
    
    // Limpa o estado salvo após restaurar
    localStorage.removeItem('plpState');
  }
});

Como ficaria?

  1. Salva a página atual: Além de salvar a posição do scroll, também estamos salvando a página atual da paginação (currentPaginationPage). Quando o usuário retorna da PDP, o sistema recarrega essa página específica da PLP.
  2. Restaura a posição do scroll: Assim que a página correta é recarregada, a posição de rolagem é restaurada.
  3. Limpeza do estado: Após restaurar o estado da página e o scroll, o localStorage é limpo para evitar acúmulo de dados desnecessários.

Veja se muda algo no seu caso.

Realmente fora isso, não vejo outro cenário positivo no momento.

Abs,
Estevão.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.