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.