Neste artigo veremos como criar a funcionalidade de scroll híbrido nas páginas da categoria e nos resultados da pesquisa.
Mas o que é um scroll híbrido? Basicamente, misture as experiências de:
- Um scroll infinito no qual os produtos são carregados na lista à medida que o usuário rola na página, sem ver o rodapé até que todos os produtos tenham terminado de carregar (assim como um aplicativo nativo em um telefone celular).
- Uma experiência de paginação clássica em que o usuário tem controle sobre quantos produtos ver por página, deixando o rodapé mais visível do que no caso de scroll infinito.
O scroll híbrido funciona da seguinte maneira:
- Ao carregar a página exibimos 12, 16 ou 20 itens (dependendo do que está definido no tpls que veremos neste tutorial)
- Quando o usuário inicia a rolagem, mais produtos são carregados automaticamente (ocultando o rodapé) até atingirem 50.
- Em seguida, um botão "ver mais produtos" e o rodapé do site são exibidos.
- Clicar neste botão carrega mais produtos e retorna ao modo "scroll infinito"
- Quando o usuário rola, mais produtos são recarregados automaticamente até chegarem a mais 60.
- Os passos são repetidos
Desta forma, garantimos que o usuário verá o conteúdo que está abaixo da lista de produtos, por exemplo, o rodapé, onde pode haver informações relevantes, como métodos de pagamento, métodos de envio, detalhes de contato, etc.
Além disso, se o usuário acessar os detalhes de um produto e voltar, ele não perderá a quantidade de produtos carregados anteriormente.
HTML
1. A primeira coisa que vamos fazer é no arquivo templates/category.tpl excluir o grid que você tem até agora e substituí-lo com o seguinte:
{% if products %} <div class="js-product-table row"> {% include 'snipplets/product_grid.tpl' %} </div> {% if pages.current == 1 and not pages.is_last %} <div class="text-center mt-5 mb-5"> <a class="js-load-more btn btn-primary"> <span class="js-load-more-spinner" style="display:none;">{% include "snipplets/svg/sync-alt.tpl" with {svg_custom_class: "icon-inline icon-spin"} %}</span> {{ 'Mostrar más productos' | t }} </a> </div> <div id="js-infinite-scroll-spinner" class="mt-5 mb-5 text-center w-100" style="display:none"> {% include "snipplets/svg/sync-alt.tpl" with {svg_custom_class: "icon-inline icon-3x svg-icon-text icon-spin"} %} </div> {% endif %} {% else %} <p class="text-center"> {{(has_filters ? "No tenemos productos en esas variantes. Por favor, intentá con otros filtros." : "Próximamente") | translate}} </p> {% endif %}
É importante manter os IDs e as classes "js -...", pois iremos conectá-los ao JavaScript.
Também precisamos adicionar a seguinte linha no começo do tpl (se você já tem, não é necessário fazer este passo)
{% paginate by 12 %}
Isso define a paginação inicial (o número de produtos que são carregados antes de você começar a fazer scroll) ao carregar a página.
2. No template search.tpl na pasta de templates, aplique uma alteração muito semelhante à etapa anterior:
{% if products %} <div class="js-product-table row"> {% include 'snipplets/product_grid.tpl' %} </div> {% if pages.current == 1 and not pages.is_last %} <div class="text-center mt-5 mb-5"> <a class="js-load-more btn btn-primary"> <span class="js-load-more-spinner" style="display:none;">{% include "snipplets/svg/sync-alt.tpl" with {svg_custom_class: "icon-inline icon-spin"} %}</span> {{ 'Mostrar más productos' | t }} </a> </div> <div id="js-infinite-scroll-spinner" class="mt-5 mb-5 text-center w-100" style="display:none"> {% include "snipplets/svg/sync-alt.tpl" with {svg_custom_class: "icon-inline icon-3x svg-icon-text icon-spin"} %} </div> {% endif %} {% else %} <p class="text-center"> {{ "No hubo resultados para tu búsqueda" | translate }} </p> {% endif %}
E também adicionar (ou substituir) o valor de paginação no início do tpl
{% paginate by 12 %}
2. Adicionamos a classe js-hide-footer-while-scrolling ao container geral do rodapé.
3. Finalmente, para a parte HTML, precisamos adicionar uma pasta SVG dentro da pasta snipplets, onde vamos criar o snipplet para o ícone que gira indicando que mais produtos estão sendo carregados, com o nome sync-alt.tpl
<svg class="{{ svg_custom_class }}" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M483.515 28.485L431.35 80.65C386.475 35.767 324.485 8 256 8 123.228 8 14.824 112.338 8.31 243.493 7.971 250.311 13.475 256 20.301 256h28.045c6.353 0 11.613-4.952 11.973-11.294C66.161 141.649 151.453 60 256 60c54.163 0 103.157 21.923 138.614 57.386l-54.128 54.129c-7.56 7.56-2.206 20.485 8.485 20.485H492c6.627 0 12-5.373 12-12V36.971c0-10.691-12.926-16.045-20.485-8.486zM491.699 256h-28.045c-6.353 0-11.613 4.952-11.973 11.294C445.839 370.351 360.547 452 256 452c-54.163 0-103.157-21.923-138.614-57.386l54.128-54.129c7.56-7.56 2.206-20.485-8.485-20.485H20c-6.627 0-12 5.373-12 12v143.029c0 10.691 12.926 16.045 20.485 8.485L80.65 431.35C125.525 476.233 187.516 504 256 504c132.773 0 241.176-104.338 247.69-235.493.339-6.818-5.165-12.507-11.991-12.507z"/></svg>
CSS
Requisito:
Ter adicionado helper classes em seu layout. Você pode seguir este pequeno tutorial para fazer isso (é só copiar e colar algumas classes, não leva mais que 1 minuto).
Adicionamos o seguinte SASS de cores em style-colors.scss.tpl (ou na stylesheet do seu layout que possui as cores e fontes da loja). Lembre-se de que as variáveis de cores e fontes podem variar em relação ao seu layout:
@mixin prefix($property, $value, $prefixes: ()) { @each $prefix in $prefixes { #{'-' + $prefix + '-' + $property}: $value; } #{$property}: $value; } {# /* // Buttons */ #} .btn{ text-decoration: none; text-align: center; border: 0; cursor: pointer; -webkit-appearance: none; -moz-appearance: none; appearance: none; text-transform: uppercase; background: none; @include prefix(transition, all 0.4s ease, webkit ms moz o); &:hover, &:focus{ outline: 0; opacity: 0.8; } &[disabled], &[disabled]:hover{ opacity: 0.5; cursor: not-allowed; outline: 0; } &-default{ padding: 10px 15px; background-color: rgba($main-foreground, .2); color: $main-foreground; fill: $main-foreground; font-weight: bold; } &-primary{ padding: 15px; background-color: $primary-color; color: $main-background; fill: $main-background; letter-spacing: 4px; &:hover{ color: $main-background; fill: $main-background; } } &-block{ float: left; width: 100%; } } button{ @extend %body-font; cursor: pointer; &:focus{ outline: 0; opacity: 0.8; } }
JS
⚠️ A partir do dia 30 de janeiro de 2023, a biblioteca jQuery será removida do código de nossas lojas, portanto, a função "$" não poderá ser utilizada.
1. JavaScript precisam ser adicionados no arquivo store.js.tpl (ou onde você tem suas funções JS). O código que precisamos é o seguinte:
{% if template == 'category' or template == 'search' %} !function() { {# /* // Infinite scroll */ #} {% if pages.current == 1 and not pages.is_last %} LS.hybridScroll({ productGridSelector: '.js-product-table', spinnerSelector: '#js-infinite-scroll-spinner', loadMoreButtonSelector: '.js-load-more', hideWhileScrollingSelector: ".js-hide-footer-while-scrolling", productsBeforeLoadMoreButton: 50, productsPerPage: 12 }); {% endif %} }(); {% endif %}
En este JS podemos encontrar algunas propiedades que podés cambiar:
Propiedade | Descrição |
---|---|
productGridSelector | É o seletor para o div que contém a lista de produtos |
spinnerSelector | O seletor do ícone giratório que é exibido quando o usuário alcança a parte inferior de tudo na tela e nenhum produto foi carregado ainda. |
loadMoreButtonSelector | Usado para ocultar ou mostrar o botão "Ver mais produtos |
hideWhileScrollingSelector | Como o nome indica, ele serve para ocultar elementos enquanto o modo “scroll infinito” é ativado |
productsBeforeLoadMoreButton | É a quantidade de produtos que serão carregados até que o botão "Ver mais" seja exibido |
productsPerPage | Número de produtos exibidos quando a página é carregada. Deve corresponder ao {% paginate by 12 %} no category.tpl e search.tpl |
Caso você precise aplicar o JS logo após o carregamento dos produtos, você pode usar a seguinte função:
afterLoaded: function() { },
Dentro do contexto, seria aplicado da seguinte forma:
spinnerSelector: '#js-infinite-scroll-spinner', loadMoreButtonSelector: '.js-load-more', hideWhileScrollingSelector: ".js-hide-footer-while-scrolling", productsBeforeLoadMoreButton: 50, productsPerPage: 12, afterLoaded: function() { console.log("test"); },
Isso pode ser útil caso você use um plug-in como o Masonry, em que você precisa acomodar os elementos sempre que forem carregados.
Pronto, você já tem o scroll híbrido em execução.