EN
Shopify 知识库 · 指南

Dawn 筛选、排序与分页:分区请求、URL 与移动抽屉

基于 Dawn v15.3.0 固定源码,追踪集合页与搜索页的筛选表单、Section Rendering 局部刷新、pushState URL、已选条件移除、价格区间、移动筛选抽屉与分页,并对照通用契约列出差距。
历史资料
请结合文中的适用版本和来源阅读。

本文基于 Dawn v15.3.0,源码固定到 ecb06c3(核验于 2026-09-29)。结论限于此提交,不表示其他版本行为相同;本篇为静态源码分析,未完成店铺运行验证。Dawn 上游已发布 v16.0.0(2026-08-10,GitHub Releases 核对),本库 Dawn 正文统一以 v15.3.0 为基线,升级前需重新核对。

对应哪些通用模式

对应集合浏览与筛选模块、Pagination,移动端筛选对应Drawer。集合页与搜索结果页共用同一个 facets 片段和 facets.js;搜索框与建议见Dawn 预测搜索。

入口与文件

文件职责何时输出
sections/main-collection-product-grid.liquid分页、渲染 facets、商品网格、pagination,含空结果分支集合模板
sections/main-search.liquid同构,paginate 每页 24;search.filters 非空才渲染 facets搜索模板
snippets/facets.liquid桌面表单、menu-drawer 抽屉、已选条件、计数、排序由上两者 render
snippets/price-facet.liquid价格区间两个文本输入价格筛选
assets/facets.jsfacet-filters-form、price-range、facet-remove页面加载
snippets/pagination.liquid页码链接 navpaginate.pages > 1

数据从哪来

  • 筛选与排序对象:collection.filters / search.filters(filter.type 为 boolean、list、price_range,active_values、values、url_to_remove、param_name)、sort_options、sort_by、products_count / all_products_count。
  • URL 参数:复选框 name 取 value.param_name,价格输入取 filter.min_value.param_name / max_value.param_name;参数命名规则见通用模块页,本文未核对实际值。
  • 商家设置(main-collection-product-grid schema):products_per_page(8–36,步长 4,默认 16)、enable_filtering、filter_type(horizontal 默认 / vertical / drawer)、enable_sorting、quick_add 等;搜索页有同名筛选设置。

交互怎样运行

  1. 表单 input 事件经 800ms 防抖触发 onSubmitHandler,无提交按钮:用 FormData 生成查询串(桌面合并排序与筛选表单)。
  2. renderPage 请求 ${pathname}?section_id=<#product-grid 的 data-id>&<查询串>,即对当前 URL 做 Section Rendering,再替换 #ProductGridContainer、各 .js-filter 组、.active-facets-*、.sorting 与计数节点;响应缓存在内存数组 filterData(以完整 URL 为键,页面会话内不失效)。
  3. history.pushState({searchParams}, '', pathname?查询串) 写回地址栏;popstate 读取 state 重新渲染。表单数据不含 page,所以任何筛选、排序变化都回到第一页。
  4. 已选条件是 <facet-remove><a href=url_to_remove>:JS 把链接设为 role="button",点击时阻止跳转并按其查询串局部刷新;“全部移除”指向 collection.url 或搜索地址。
  5. 价格区间是两个 type="text" inputmode="decimal" 输入,price-range 在 change 时按 data-min / data-max 钳制,keydown 只放行数字、分隔符与少数控制键;没有滑块,不依赖拖拽(money_without_currency 输出与提交参数的小数格式是否一致,未核验)。
  6. 移动端:<menu-drawer data-breakpoint="mobile"> 内的 details,来自 global.js 的 MenuDrawer(Escape 关闭、trapFocus、失焦关闭),每个筛选组是嵌套 details。勾选立即请求,“Apply”只是点击 summary 关闭抽屉。horizontal / vertical 时抽屉仅在 <750px 显示,drawer 时各宽度都用。
  7. 分页不由 JS 接管:pagination 输出普通 <a href>,换页是整页导航;layout/theme.liquid 的 <title> 在 current_page != 1 时追加“Page N”。
  8. 无 JS:排序与筛选表单无 action、提交按钮或 noscript 回退(全仓库 noscript 搜索无命中),已选条件与页码仍是真实链接;Apply 依赖 onclick。

与通用契约的一致与差距

契约(集合浏览与筛选)Dawn v15.3.0判断
URL 可重建、可返回pushState + popstate 重渲染;地址即查询串一致;canonical_url 是否含筛选参数、是否有 noindex 未核验(全仓库搜索 noindex、rel="next"、rel="prev" 无命中)
结果计数通知.product-count 为 role="status",刷新后替换其中 #ProductCount 内容一致
加载中旧结果保留给 .collection 加 loading 类与图标,无 aria-busy(全仓库搜索无命中)部分一致
取消过期请求、错误处理fetch 无 AbortController、无 response.ok 检查、无 catch差距:乱序响应会互相覆盖,失败时 loading 状态可能不复位(静态推断)
焦点保持复选框所在 .facets-wrap 被整体替换,主题显式把焦点移到该组 summary(移动端为返回按钮);价格文本输入例外;facets.js 仅此一处 .focus()差距:不会回页首,但焦点从被操作的控件跳到组标题;排序下拉与被点击的已选标签随 innerHTML 被替换,未见恢复焦点代码,实际落点未核验
自动应用须事先告知(WCAG 3.2.2)800ms 后自动请求;排序下拉的 aria-describedby 指向 a11y-refresh-page-message,其默认英文文案表示选择会整页刷新差距:文案与 JS 局部刷新不符;复选框无说明
筛选值为 0count == 0 且未选中时 disabled 并加 disabled 类,仍显示一致(显示为不可选)
分组与已选条件每组 fieldset + 视觉隐藏 legend,summary 的 aria-label 含已选数量;标签文字为“筛选名: 值”并附视觉隐藏“Remove filter”,另有“全部移除”一致
零结果提示文案加指向 collection.url 的“少用筛选”链接,整页跳转;已选标签仍可移除;已读分支中无客服入口,HTTP 状态码未核验部分一致
计数文案桌面按 value.count == 1 选单复数键,移动端写成 value.count == '1'(字符串)疑似不一致,Liquid 中二者是否等价未核验
抽屉作为模态menu-drawer 有焦点圈定与 Escape,但未见 role="dialog" / aria-modal(facets.liquid 中无命中)差距
分页链接与 aria-currentnav 带 aria-label,当前页 aria-current="page"(role="link" 无 href),上一页 / 下一页有 aria-label一致;经分区响应重渲染的页码链接是否带 section_id 未核验

定制入口与风险

商家可改上述 section 设置;筛选项本身来自 Search & Discovery,不在主题里。开发侧耦合点:#ProductGridContainer、#product-grid 的 data-id、#ProductCount、.js-filter、FacetFiltersFormMobile 等 id 被 facets.js 硬编码;renderAdditionalElements 每次重新调用 bindEvents(),会给未被替换的元素重复绑定监听,影响未核验;分区被 innerHTML 替换后,global.js 启动时给 [id^="Details-"] summary 设置的 role、aria-expanded 不会自动补到新节点(推断,未验证)。

建议的验证范围

本篇均未执行:多筛选组合的 URL 与后退前进;限速下连续勾选,确认乱序与失败复位;零结果 URL 的状态码与 canonical;键盘完成筛选、移除、排序并记录焦点落点;读屏软件核对计数与排序说明;<750px 抽屉的焦点循环;第二页页码链接是否保留筛选参数。

源码基线