当前位置: 首页 > news >正文

天津网站建设技术外包软件开发定制平台

天津网站建设技术外包,软件开发定制平台,中国网络运营商排名,wordpress 上一页在做 Shopify 商城二开的时候,我们常常会遇到集合页(Collection Page)用户体验不够流畅的问题:默认的 分页 需要用户不断点击「下一页」才能看完所有商品,流程比较割裂。集合页顶部有时需要插入 活动 Banner 图&#x…

在做 Shopify 商城二开的时候,我们常常会遇到集合页(Collection Page)用户体验不够流畅的问题:

  • 默认的 分页 需要用户不断点击「下一页」才能看完所有商品,流程比较割裂。
  • 集合页顶部有时需要插入 活动 Banner 图,但 Shopify 默认没有直接的插槽。

于是,我改造了 Collection 模板,增加了两个功能:

  • 在第一页商品列表前插入 Banner 图片
  • 将传统分页替换为「点击加载更多」按钮

在原来的结构中增加banner图和按钮的结构 {% if section.settings.img != blank and paginate.current_page == 1 %}保证了只会加载一次,防止重复加载图

<ul id="product-grid" data-id="{{ section.id }}" class=" grid product-grid grid--{{ section.settings.columns_mobile }}-col-tablet-down grid--{{ section.settings.columns_desktop }}-col-desktop {% if section.settings.quick_add == 'bulk' %} collection-quick-add-bulk{% endif %} ">{%- assign cols = section.settings.columns_desktop | plus: 0 -%}{%- assign gutter = 'var(--grid-desktop-horizontal-spacing)' -%}{% if section.settings.img != blank and paginate.current_page == 1 %}<li class="grid__item grid__item--banner pc" style=" width: calc({{ 200 | divided_by: cols }}% - (({{ cols }} - 2) / {{ cols }}) * {{ gutter }}); max-width: calc({{ 200 | divided_by: cols }}% - (({{ cols }} - 2) / {{ cols }}) * {{ gutter }});"><img src="{{ section.settings.img | image_url: width: '1920x' }}" width="{{ section.settings.img.width }}"height="{{ section.settings.img.height }}" loading="lazy" alt="{{ section.settings.img.alt }}"></li>{% endif %}{% assign skip_card_product_styles = false %}{%- for product in collection.products -%}{% assign lazy_load = false %}{%- if forloop.index > 2 -%}{%- assign lazy_load = true -%}{%- endif -%}<li class="grid__item{% if settings.animations_reveal_on_scroll %} scroll-trigger animate--slide-in{% endif %}" {% ifsettings.animations_reveal_on_scroll %} data-cascade style="--animation-order: {{ forloop.index }};" {% endif %}>{% render 'card-product'%} <!--产品卡组件 --></li>{%- assign skip_card_product_styles = true -%}{%- endfor -%}
</ul>
<div class="Load-More-inner"><!--使用 paginate 提供“筛选后”的真实总数与每页条数 --><div class="Load-More-number text-text" id="LoadMoreNumber" data-total="{{ paginate.items }}"data-per-page="{{ paginate.page_size }}"><!-- 左侧显示“当前已加载数”,初始为当前页已渲染的产品数量 --><span id="LoadedCount">{{ collection.products | size }}</span>of<span id="TotalCount">{{ paginate.items }}</span></div>{% if paginate.pages > 1 %}<!-- 由 JS 动态计算下一页 --><div class="Load-More btn_4" id="LoadMoreBtn">Load More</div>{% endif %}</div>

Shopify 默认的集合页分页机制,用户每次都要跳页,体验割裂。JS 逻辑优化:初始化 → 监听 → 点击加载 → 状态更新。

  • UI 与数据同步:点击加载、筛选、Section 重渲染,都会自动更新按钮和计数。
  • 兼容 Shopify:监听 shopify:section:load / facets:updated / MutationObserver。
  • 避免重复加载:通过 Math.ceil(totalLoaded / perPage) 动态计算下一页。
  • 用户体验优化:按钮有 Loading 状态,加载完毕后自动隐藏。

Ajax 异步加载 + DOM 解析:点击按钮后,用 fetch 拉取下一页 HTML,再用 DOMParser 抽取 #product-grid 里的 <li> 追加。每次加载后,调用 updateLoadMoreUI(),判断按钮显示隐藏。

fetch(url.href).then(r => r.text()).then(html => {const doc = new DOMParser().parseFromString(html, 'text/html');const nextGrid = doc.querySelector('#ProductGridContainer #product-grid');const nextProducts = nextGrid.querySelectorAll('li.grid__item:not(.grid__item--banner)');nextProducts.forEach(item => productGrid.appendChild(item));updateLoadMoreUI();});

由于 Shopify 的 Facet Filter 筛选会刷新整个产品区块,如果不处理,Load More 状态会错乱。我加了一个 MutationObserver,监听 #product-grid 子元素变化:

const observer = new MutationObserver(() => updateLoadMoreUI());
observer.observe(productGrid, { childList: true, subtree: true });

完整的js代码参考

<script>
/* 封装一个计算&展示状态的方法 */
function updateLoadMoreUI() {const productGrid = document.getElementById('product-grid');const loadMoreNumber = document.getElementById('LoadMoreNumber');const btn = document.getElementById('LoadMoreBtn');if (!productGrid || !loadMoreNumber || !btn) return;// 统计当前已加载(排除 banner)const totalLoaded = productGrid.querySelectorAll('li.grid__item:not(.grid__item--banner)').length;// 读取筛选后的“总数/每页”const totalProducts = parseInt(loadMoreNumber.dataset.total, 10) || 0;const perPage = parseInt(loadMoreNumber.dataset.perPage, 10) || 1;// 更新显示const loadedEl = document.getElementById('LoadedCount');const totalEl = document.getElementById('TotalCount');if (loadedEl) loadedEl.textContent = totalLoaded;if (totalEl) totalEl.textContent = totalProducts;// 如果已加载 >= 总数,则隐藏按钮if (totalLoaded >= totalProducts || perPage <= 0) {btn.style.display = 'none';} else {btn.style.display = 'inline-flex'; }
}/* 页面初次加载/筛选后(区块被替换)也确保状态正确 */
document.addEventListener('DOMContentLoaded', updateLoadMoreUI);
window.addEventListener('shopify:section:load', updateLoadMoreUI);
window.addEventListener('shopify:section:render', updateLoadMoreUI);
document.addEventListener('facets:updated', updateLoadMoreUI);//新增 MutationObserver,监听 product-grid 变化(筛选结果替换时触发)
document.addEventListener('DOMContentLoaded', () => {const productGrid = document.getElementById('product-grid');if (productGrid) {const observer = new MutationObserver(() => {updateLoadMoreUI();});observer.observe(productGrid, { childList: true, subtree: true });updateLoadMoreUI(); // 初始执行一次}
});document.addEventListener('click', function (e) {const btn = e.target.closest('#LoadMoreBtn');if (!btn) return;const productGrid = document.getElementById('product-grid');const loadMoreNumber = document.getElementById('LoadMoreNumber');if (!productGrid || !loadMoreNumber) return;// 基于已加载数量/每页动态算下一页(用 Math.ceil 避免重复加载)const perPage = parseInt(loadMoreNumber.dataset.perPage, 10) || 1;const totalProducts = parseInt(loadMoreNumber.dataset.total, 10) || 0;const totalLoadedBefore = productGrid.querySelectorAll('li.grid__item:not(.grid__item--banner)').length;const currentPage = Math.ceil(totalLoadedBefore / perPage);const nextPage = currentPage + 1;// 从现有 URL 保留所有筛选参数,只改 pageconst url = new URL(window.location.href);url.searchParams.set('page', nextPage);// 可选 loading 态const originalBtnText = btn.textContent;btn.textContent = 'Loading…';btn.disabled = true;fetch(url.href).then(response => response.text()).then(html => {const parser = new DOMParser();const doc = parser.parseFromString(html, 'text/html');// 取下一页对应的商品网格const nextGrid = doc.querySelector('#ProductGridContainer #product-grid');if (!nextGrid) {btn.style.display = 'none';return;}const nextProducts = nextGrid.querySelectorAll('li.grid__item:not(.grid__item--banner)');if (!nextProducts.length) {btn.style.display = 'none';return;}// 追加产品nextProducts.forEach(item => productGrid.appendChild(item));updateLoadMoreUI(); // 追加完产品后立刻更新 UI}).catch(err => {console.error('Load More Error:', err);}).finally(() => {btn.textContent = originalBtnText;btn.disabled = false;updateLoadMoreUI(); //兜底再更新一次});
});
</script>

http://www.dtcms.com/a/556404.html

相关文章:

  • 北京托管网站网站开始怎么做的
  • 网站备案模板创建微信公众号步骤
  • 做网站用到ps么网站色彩搭配方案
  • android 移动网站开发详解长沙网站建设公司哪家专业
  • 珠海网站建设珠海公司网站开发交接注意事项
  • 外贸企业网站制作公司现在的网站开发用什么技术
  • net网站阿里云主机配置抖音seo优化
  • wordpress建多个网站全景制作软件app
  • 建设部网站 造价工程师wordpress扫光
  • 樱桃企业网站管理系统常州网站建设方案策划
  • 政务大厅网站建设管理制度软件工程培训机构哪家好
  • 唐山网站制作制作网页素材图片
  • 余姚建设网站的公司免费服务器永久
  • 网站设置在哪里找做网站 傻瓜软件
  • 手机html5网站模板沈阳做网站一诚金网络专业
  • 好看的个人网站设计电商详情页模板免费下载
  • 山东环保行业网站开发云南百度公司
  • 如何推广网站最有效哈尔滨免费做网站
  • 开发网站费用房山青岛网站建设
  • seo网站推广作用android软件开发前景
  • 网站开发地图板块浮动网站设计的难点
  • 温州网站维护工作电子商务平台经营者
  • 宏润建设集团网站企业网站的优点
  • 网站优化名词解释郑州航空港区建设局网站
  • c2c网站名称和网址网站备案要多久时间
  • 昌邑微信网站建设公司河南网站建设服务
  • 网站建设培训证书怎么判断公司是不是外包
  • 网站开发建设费用包括那些dw对网站建设有哪些作用
  • 网站开发技术部绩效考核住房城乡建设干部学院网站
  • 芜湖小学网站建设wordpress 主题改多频道