# 事件

> 使用 on() 和 off() 監聽結帳流程的開啟、關閉及同意記錄，並了解每個事件只能有一個監聽器的規則。

結帳流程會向你的頁面回報其正在進行的操作。使用 `on()` 訂閱：

```js
entase.on('checkout.ready', payload => {
  console.log('checkout open for', payload.context.eventID);
});
```

## 每個事件名稱只能有一個監聽器

`on()` 會為每個事件名稱儲存**一個**回呼函式。為同一名稱註冊第二個回呼函式時，會取代第一個 – 而不會新增至其中：

```js
entase.on('checkout.closed', a);
entase.on('checkout.closed', b);   // a is gone; only b runs
```

`off()` 會移除為某個名稱註冊的任何內容。它會忽略你傳入的任何回呼函式，因此 `off('checkout.closed', b)` 和 `off('checkout.closed')` 的作用相同。

如果頁面的多個部分需要對同一事件作出反應，請註冊一個回呼函式，並從中分派處理。

## 一次訂閱多個事件

兩個方法都接受以空格分隔的字串或名稱陣列，並為每個名稱註冊相同的回呼函式：

```js
entase.on('checkout.ready checkout.closed', payload => {
  console.log(payload.name);
});

entase.off(['checkout.ready', 'checkout.closed']);
```

## 負載資料

每個回呼函式都會接收一個物件：

| 欄位 | 類型 | 說明 |
|---|---|---|
| `name` | string | 事件名稱；當一個回呼函式處理多個事件時很有用。 |
| `context` | object | 包含 `eventID` – 此結帳流程所屬的活動。 |
| `data` | object | 事件專屬的詳細資料。 |

## 可用事件

| 名稱 | 觸發時機 |
|---|---|
| `checkout.ready` | 結帳流程已載入並可供互動。此時用戶端亦會交回你傳遞給 `book()` 的 `clientContext`。 |
| `checkout.closed` | 結帳流程已關閉。用戶端會移除面板或視窗，並清除背景遮罩。 |
| `checkout.consent` | 訪客已回覆條款通知。接受時，`data.consent` 為 `true`；用戶端會記住此選擇，以便下次略過此步驟。 |

```js
entase.on('checkout.closed', () => {
  document.body.classList.remove('checkout-open');
});

entase.on('checkout.consent', payload => {
  if (payload.data.consent) console.log('terms accepted');
});
```

## 監聽器會跨個別預訂持續保留

監聽器屬於實例，而非某次預訂。建立用戶端後只需註冊一次，它們便會套用至每次 `book()` 呼叫。使用 `payload.context.eventID` 區分不同預訂：

```js
const entase = new Entase({ pk: 'YOUR_PUBLISHABLE_KEY' });

entase.on('checkout.closed', payload => {
  refreshAvailability(payload.context.eventID);
});
```

呼叫 `destroy()` 會停止所有監聽器 – 實例會完全停止監聽來自結帳流程的訊息。

## 來自其他來源的訊息會被忽略

用戶端只接受來自 Entase 結帳流程來源的訊息，因此頁面上不相關的 `postMessage` 流量絕不會傳送到你的回呼函式。
