Shopify 主题开发:用 AJAX 实现博客分页无刷新加载效果

在 Shopify 的 blog 模板中,默认的分页会整页刷新。如果你想优化用户体验,可以使用 fetch 来做无刷新分页切换。本文分享一个可直接使用的示例,并解释其中的关键点。


1、需求场景

  • 博客文章较多,想按页展示,每页 6 篇文章

  • 点击分页按钮时,不刷新整页,只替换文章列表和分页导航

  • 支持浏览器前进后退按钮

  • 切换分页后,页面自动平滑滚动到文章区域


2、核心代码示例

以下是完整的示例:

{%- paginate blog.articles by 6 -%}
  <div class="main-cases page-width section-{{ section.id }}-padding">
    <div class="section-header">
      <h2 class="head_title my_h_28 my_m_28">{{ section.settings.heading }}</h2>
      <p class="head_text my_h_18 my_m_12">{{ section.settings.text }}</p>
    </div>

    <div class="blog-articles">
      {%- for article in blog.articles -%}
        <div
          class="blog-articles__article article{% if settings.animations_reveal_on_scroll %} scroll-trigger animate--slide-in{% endif %}"
          {% if settings.animations_reveal_on_scroll %}
            data-cascade
            style="--animation-order: {{ forloop.index }};"
          {% endif %}
        >
          {%- render 'cases-card',
            article: article,
            media_height: section.settings.image_height,
            media_aspect_ratio: article.image.aspect_ratio,
            show_image: section.settings.show_image,
            show_date: section.settings.show_date,
            show_author: section.settings.show_author,
            show_excerpt: true
          -%}
        </div>
      {%- endfor -%}
    </div>

    {%- if paginate.pages > 1 -%}
      <div class="pagination-wrapper">
        {%- render 'pagination', paginate: paginate -%}
      </div>
    {%- endif -%}
  </div>
{%- endpaginate -%}

<script>
  document.addEventListener('click', function (e) {
    const link = e.target.closest('.pagination__item');
    if (link && link.tagName === 'A') {
      e.preventDefault();
      const url = link.getAttribute('href');
      if (url) {
        fetchPage(url);
      }
    }
  });

  function fetchPage(url) {
    fetch(url)
      .then(response => response.text())
      .then(html => {
        const parser = new DOMParser();
        const doc = parser.parseFromString(html, 'text/html');

        const newArticles = doc.querySelector('.blog-articles');
        const newPagination = doc.querySelector('.pagination-wrapper');

        if (newArticles && newPagination) {
          document.querySelector('.blog-articles').innerHTML = newArticles.innerHTML;
          document.querySelector('.pagination-wrapper').innerHTML = newPagination.innerHTML;

          // 更新 URL,方便后退按钮
          history.pushState(null, '', url);

          

          // 平滑滚动到文章区域
          const mainCases = document.querySelector('.main-cases');
          if (mainCases) {
            mainCases.scrollIntoView({
              behavior: 'smooth',
              block: 'start'
            });
          }
        }
      })
      .catch(err => console.error(err));
  }

  // 支持浏览器前进/后退按钮
  window.addEventListener('popstate', () => {
    fetchPage(location.href);
  });
</script>

3、关键点解释

1. Liquid paginate 标签
通过 {% paginate blog.articles by 6 %} 限制每页显示 6 篇文章。

2. 渲染分页导航
{% render 'pagination', paginate: paginate %} 使用 Shopify 的分页分块。

3. 用 JS 阻止默认跳转
通过 document.addEventListener('click', ...) 捕获分页按钮点击事件,阻止默认行为,改用 fetch 加载新页面内容。

4. 用 DOMParser 更新局部内容
从返回的 HTML 中提取 .blog-articles.pagination-wrapper,只替换这两块内容。

5. history.pushStatepopstate
使用 history.pushState 更新地址栏,监听 popstate 来支持浏览器前进/后退操作。

6. 平滑滚动
切换分页后,调用 .scrollIntoView({ behavior: 'smooth' }) 平滑滚动到文章区域顶部。


 4、注意事项

  • 确保 .pagination-wrapper 外层要包裹好,避免替换失败。

  • 该方案适用于 Dawn 等常见 Shopify 主题。


5、小结

这个方案用原生 JS 就能实现无刷新分页,无需额外依赖复杂的前端框架。
在 Shopify 的 blogcollections、甚至搜索结果页都可以用类似的方式实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值