<script> 标签。On cart update 有一个 Reset to default 操作,可恢复其初始模板;Initialization 没有,所以在清空之前请自行保留一份副本。
商家过去用脚本实现的很多功能现在已成为内置设置。请先查看编写脚本之前:设置在购物车重新设计后仍能继续工作,而你的脚本可能不行。
该使用哪个插槽
Initialization
window.aftersell.cart 的形式提供。
你在这里进行的设置调用(configure(...)、events.on(...)、hooks.*)即使在购物车尚未完全启动之前,也可以安全地放在脚本顶部调用;它们会被缓冲,并在购物车启动后应用。读取或更改购物车的操作(如 addItem 或 getCart)应在 ready() 或事件处理函数内部运行。
该插槽初始包含三个已注释掉的示例——每次添加商品时打开抽屉、响应 cart_loaded,以及隐藏免费赠品行——因此未经修改的 Initialization 脚本不会执行任何操作。取消注释其中一个来试用,或将它们替换掉。
这个插槽最自然的形态是不涉及任何事件的一次性注册:注册一次行为,然后让购物车从此开始应用它。在不改变总额的前提下从抽屉中隐藏免费赠品行,就是随附的示例:
registerLineTransform 会在每一行渲染时运行,而 setHidden 仅影响显示,所以该行仍保留在购物车中并计入总额,只是不在抽屉中显示。参阅隐藏和重新标记购物车行以了解转换还能做什么。
读取购物车的操作要放在 ready() 内部:
shadowRoot:购物车渲染在 shadow root 内部,所以 document.querySelector 看不到抽屉中的任何内容。
On cart update
cart_updated 订阅的锁定包装器,所以你只需编辑主体部分,你的代码会接收到更新后的 cart。
这个插槽适用于必须在每次购物车变化时重新评估的规则。免费赠品门槛是经典案例(消费满 $75 送免费托特包),因为答案取决于当前内容,而且没有其他方式能在内容变化时通知你:
让购物车保持在期望状态
if (shouldHaveGift === hasGift) return; 这一行是这段代码安全的关键,并且它可推广到所有让购物车保持在期望状态的脚本。这个插槽既响应购物车变化又会引起变化,所以每次 addItem 或 removeItem 都会重新进入它。描述你想要的状态,将它与现有状态进行比较,并在两者已经一致时提前返回,这样处理函数一次执行就会收敛,而不会陷入循环。参阅两条规则了解应避免的无防护版本,以及为什么载荷是只读的。
在较慢的商店中,还值得保留一个模块级的进行中标志,这样两次快速变化就不会在第一次添加完成之前同时发起添加。
cart_updated 仅在首次加载之后的变化时触发(事件时序),所以这个插槽中的脚本不会协调页面加载时已经满足条件的购物车。若要同时处理两种情况,请在 Initialization 插槽中用同一个函数订阅 cart_loaded 和 cart_updated。参阅达到门槛时自动添加免费赠品。脚本出错时
configure、events.on 或 hooks.register* 都不会被注册。当代码看起来没问题却出现”我的处理函数从不触发”时,这通常就是原因。
购物车会在浏览器控制台中指出出错的行,并且每个插槽以自己的文件名运行(aftersell-cart-init.js 和 aftersell-cart-cart-update.js),所以你可以从 DevTools 的 Sources 面板打开任意一个并设置断点。参阅调试了解确切的报错信息,以及捕获未输出到控制台的 hook 失败的调试通道。
由于 cart_loaded 会向迟来的订阅者重放,注册顺序从不重要。最安全的结构是先注册所有内容,然后在处理函数内部执行有风险的工作,这样抛出的错误只会被隔离在该处理函数中。