> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aftersell.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 加入购物车拦截

> 为什么 Aftersell 会接管加入购物车、如何判断表单是否被拦截，以及为表单退出拦截的所有方式。

当购物者点击**加入购物车**时，Aftersell 通常会自己处理这次添加，而不是让主题去做。本页解释为什么这样做、这对你添加的脚本意味着什么，以及如何为某个表单或所有表单关闭这一行为。

大多数店铺永远不需要改动这些设置。如果你的某个脚本在加入购物车时不再触发，或者某个加入购物车按钮表现异常，请继续阅读。

## 拦截做了什么

Aftersell 在主题之前监听加入购物车提交。当它识别到一次提交时，会：

1. 阻止事件，让页面上没有其他任何东西处理这次点击。
2. 自己把这次添加发送给 Shopify。
3. 打开 Aftersell Cart 抽屉。

第 1 步是最重要的一步，也是本页存在的原因。

## 它为什么存在

如果没有它，两个购物车都会响应同一次点击。主题会添加商品并打开自己的抽屉，Aftersell 会添加商品并打开我们的抽屉，购物者就会看到两个购物车，而且商品往往被添加了两次。

阻止事件是保证只添加一次、只有一个购物车的最简单方式。

## 它的代价

阻止事件是对**所有人**都阻止，不仅仅是主题。任何其他监听同一次加入购物车的代码都会停止运行：你的分析、跟踪像素、订阅或套装应用、你自己添加的脚本。

它是静默失败的。浏览器控制台里什么都不会出现，添加本身仍然有效，所以常见症状是数字对不上，而不是明显的功能损坏：

* GA4、Meta 或 TikTok 中缺少 `add_to_cart` 事件
* 订阅或套装应用在产品页可用，但通过购物车走时不行
* 你自己在表单上的 `addEventListener` 从不触发

如果这些情况听起来很熟悉，本页就是原因，下面是解决办法。

## Aftersell 何时不拦截

拦截并非始终开启。以下情况下 Aftersell 会让加入购物车照常运行：

* \*\*它识别出你的主题的购物车。\*\*在 Aftersell 知道如何配合的主题上，它会让主题自己的购物车变为惰性，而不是阻止事件，然后让主题正常执行添加。你的脚本一如既往地运行。参见下面的[Aftersell 识别的主题](#which-themes-aftersell-recognizes)。
* \*\*表单没有添加行项目。\*\*没有变体 `id` 也没有 `items[]` 的表单不会被处理。
* **你已经退出**——使用下面的某种方法。

当 Aftersell 不执行添加时，它仍会监视购物车请求，看到时就打开抽屉。参见[做选择之前：会有什么变化](#before-you-choose-what-changes)。

## Aftersell 识别的主题

| 主题                            |                                                                                   |
| ----------------------------- | --------------------------------------------------------------------------------- |
| **Dawn** 以及 Shopify 的其他免费主题家族 | Craft、Colorblock、Crave、Origin、Publisher、Refresh、Ride、Sense、Spotlight、Studio、Taste |
| **Horizon**                   | Shopify 当前的默认主题                                                                   |
| **Impulse**                   |                                                                                   |

Aftersell 匹配的是**主题的构建方式**，而不是它的名字，所以从上述任何一个主题分叉出来的自定义主题通常也能被识别，包括 Aftersell 从未见过的私有构建。

<Note>
  反过来的情况也会发生：经过大量定制的构建可能与其父主题相差过远，即使主题仍叫作 "Dawn"，Aftersell 也不再能识别它。在这份列表上使识别很可能发生，但并非必然。
</Note>

## 你的选项

选择能解决你问题的最窄的一种。每一行放弃的东西都比上一行更多。

| 选项                                                                   | 范围        | Aftersell 是否仍打开抽屉 |
| -------------------------------------------------------------------- | --------- | ----------------- |
| [`registerSkipAddToCartRule`](#per-form-a-rule-in-code)              | 你的规则挑中的表单 | 是，通过购物车请求         |
| [`aftersell-cart-skip-atc`](#per-form-a-class-in-your-theme)         | 一个表单或按钮   | 是，通过购物车请求         |
| [`skip_add_to_cart_interceptor`](#whole-store-turn-interception-off) | 店铺上的每个表单  | 是，通过购物车请求         |

### 做选择之前：会有什么变化

退出拦截会把添加交回给你的主题，这就带来两个在你挑选之前值得回答的问题：你的购物车是否仍会打开，以及主题自己的购物车是否会跟着冒出来。

#### 你的购物车还会打开吗？

通常会，你不用做任何事情。无论谁执行添加，Aftersell 都会监视发往 Shopify 的请求，看到时就按照你正常的**添加商品时打开购物车**设置打开抽屉。你不需要自己调用任何东西。

有三种情况会打破这一点，都有对应的解决办法：

\*\*添加发到了 Shopify 购物车端点之外的地方。\*\*Aftersell 监视你自己域名上的 `/cart/add`、`/cart/change`、`/cart/update` 和 `/cart/clear`。通过自己的端点添加然后再同步购物车的应用对此不可见。请在该应用的添加完成后自己打开购物车：

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.actions.refresh().then(() => {
  window.aftersell.cart.actions.open();
});
```

\*\*点击和请求之间超过大约三秒。\*\*Aftersell 把紧随一次真实点击或按键的添加视为由购物者驱动。超出这个时间窗口后，它就会被视为后台添加，除非你开启相应选项，否则不会打开抽屉：

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.configure({ open_on_background_add: true });
```

**你的购物车设置不允许打开。**如果**添加商品时打开购物车**关闭，或者你设置了 `open_on_add_to_cart: 'never'`，就没有东西会打开抽屉。这属于按配置正常工作。

#### 主题自己的购物车会不会也打开？

这是这些退出方式带来的风险，答案取决于你的主题。

让主题的购物车变得惰性这件事和拦截是**分开的**，无论如何都是在页面加载时发生的，所以这里的任何退出方式都不会把它切换回来。在[已识别列表](#which-themes-aftersell-recognizes)上的主题上，主题自己的购物车会保持安静，购物者看到的只有一个购物车，就是你的。

在 Aftersell 不识别的主题上，没有什么在压制主题的购物车。退出拦截意味着主题会像以前一样处理添加，包括打开自己的抽屉或跳转到 `/cart`，同时 Aftersell 根据它看到的请求打开自己的抽屉。这样就有两个购物车，而拦截的初衷正是防止这种情况。

如果出现这种情况，你有三种选择：让该表单继续保留拦截、使用不覆盖导致问题表单的更窄退出方式，或者在你自己的主题代码里阻止主题自身的购物车。

<Tip>
  先在测试或未发布的主题上开启退出。如果主题自己的购物车出现在了以前没有的位置，说明你的主题不是 Aftersell 识别的主题，你需要为那些表单保留拦截。
</Tip>

<Note>
  这只适用于加入购物车。用 `aftersell-cart-wont-open-cart` 类让**购物车图标**绕过 Aftersell 则不同：购物车图标点击不发送请求，所以 Aftersell 没有可监视的东西，抽屉不会打开。参见下文。
</Note>

### 按表单：一条代码里的规则

首选方案。注册一条对你想放行的表单返回 `true` 的规则：

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.hooks.registerSkipAddToCartRule((form) =>
  form.hasAttribute('data-skip-aftersell')
);
```

把它放到 **Cart settings → Custom script → Initialization**。规则是累加式的：你的规则和其他任何规则一起运行，任何返回 `true` 的规则都会跳过该表单。完整细节见 [Hooks](/zh/aftersell/cart/sdk-hooks#registerskipaddtocartrule)。

### 按表单：在主题里加一个类

如果你不想写规则，可以在主题里添加 `aftersell-cart-skip-atc` 类：

```html theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
<form action="/cart/add" method="post" class="aftersell-cart-skip-atc">
```

<Note>
  对表单提交而言，这个类必须放在**表单元素本身**上。放在父 `div` 上无效。对于不通过表单提交而添加到购物车的按钮，这个类可以放在按钮上或它周围的任何元素上。
</Note>

### 全店：关闭拦截

粗粒度选项。加入购物车的行为会在每个表单上与你的主题原本完全一致：

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.configure({ skip_add_to_cart_interceptor: true });
```

<Warning>
  这个选项**只在购物车加载时读取一次**。它只在你购物车的 **Initialization** 脚本中生效。之后设置它（在 `ready()` 内部或从事件处理函数中）没有效果，并且会静默失败。
</Warning>

只有当按表单的选项都不适用时才使用它，例如当你需要豁免的表单是由其他应用创建、你无法可靠识别它们时。

## 购物车图标是分开的

页头的购物车图标由它自己的拦截器处理，也有自己的退出方式。关闭加入购物车拦截不会改变购物车图标的行为，反之亦然。

点击购物车图标会打开 Aftersell 抽屉，而不是跳转到 `/cart`。要让某个图标或按钮不受影响，请给它或它周围的任意元素添加 `aftersell-cart-wont-open-cart` 类：

```html theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
<a href="/cart" class="aftersell-cart-wont-open-cart">Cart</a>
```

之后这个控件就会做主题原本让它做的事情，通常是跳转到购物车页面。Aftersell 完全退出，所以**抽屉不会打开**。与加入购物车不同，这里没有请求可监视，所以如果你希望购物车通过这个控件打开，就必须自己说清楚：

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
document.querySelector('#my-cart-link').addEventListener('click', (event) => {
  event.preventDefault();
  window.aftersell.cart.actions.open();
});
```

同样的静音问题也适用于这里：因为 Aftersell 阻止了点击，你的分析和像素也看不到购物车图标的点击。如果这就是你要修复的全部问题，可以保留抽屉并停止静音：

```js theme={"theme":{"light":"snazzy-light","dark":"github-dark"}}
window.aftersell.cart.configure({ skip_open_cart_interceptor: true });
```

你的监听器会运行，抽屉仍然会打开，点击仍然不会跳转到 `/cart`。完整细节见 [Configure](/zh/aftersell/cart/sdk-configure#skip_open_cart_interceptor)。

<Note>
  要更改*哪些*元素打开购物车，而不是关闭它们，请使用 **Cart settings → Advanced → Cart icon selector**，而不是编辑你的主题。
</Note>

## 后续阅读

* **[Configure](/zh/aftersell/cart/sdk-configure)**：每个 SDK 选项，包括这里引用的那些。
* **[Hooks](/zh/aftersell/cart/sdk-hooks)**：按表单和按行的控制。
* **[从页面构建器打开抽屉](/zh/aftersell/cart/sdk-use-case-page-builder)**：适用于 Replo、PageFly、GemPages 以及以自己方式加入购物车的自定义按钮。
