AMP

建立座位表

重要事項:此文件不適用於您目前選取的格式 電子郵件

座位表是票務網站應用程式的重要組成部分,但在 AMP 中實作可能很困難。請繼續閱讀以了解如何透過結合可用的 AMP 元件在 AMP 中實作座位表。

實作以下所述做法的即時範例,請參閱此處

需要的 AMP 元件

讓我們先檢閱需要的元件

amp-pan-zoom

amp-pan-zoom 允許透過雙擊和 Pinch 手勢縮放和平移內容。此元件作為座位表實作的基礎。

amp-list

amp-list 從 CORS JSON 端點動態擷取內容,並使用提供的範本呈現。用於擷取目前的座位表可用性,以便使用者始終獲得最新的資料。

amp-bind

amp-bind 為頁面新增互動性。此處需要用來追蹤已選取多少座位。

amp-selector

amp-selector 代表一個控制項,該控制項呈現選項選單,並讓使用者從中選擇。整個座位表可以視為選項選單,其中每個座位都是一個選項。它讓您可以使用 CSS 表達式,更輕鬆地設定已選取座位的樣式。例如,以下表達式會在選取座位後,以橘色填滿座位。

rect[selected].seat {
  fill: var(--orange-theme);
}

需求

  1. 若要將座位表繪製為 SVG,其中每個座位都以 rect 元素表示,您需要每個座位的相關資訊:位置 xywidthheight,以及可能的 rxry 以圓角化矩形的角落。
  2. 每個座位的唯一識別碼,可用於預訂。
  3. 座位表整體寬度和高度的量測值,用於 viewbox 屬性中。

繪製座位表

座位表透過 amp-listamp-mustache 呈現。從 amp-list 呼叫接收資料後,您可以使用所述資料來迭代座位

<svg preserveAspectRatio="xMidYMin slice" viewBox="0 0 {{width}} {{height}}">
{{#seats}}
<rect option="{{id}}" role="button" tabindex="0" class="seat {{unavailable}}" x="{{x}}" y="{{y}}" width="{{width}}" height="{{height}}" rx="{{rx}}" ry="{{ry}}"/>
{{/seats}}
</svg>

設定無法選取座位的樣式

在上述範例中,{{unavailable}} 是 JSON 端點傳回的欄位值,用於設定無法選取座位的樣式。此方法不允許您在座位無法選取時移除 option="" 等屬性,因為範本無法包裝整個頁面的 <html> 元素。

另一種更詳細的方法是重複標記,如下所示

{{#available }}<rect option="" role="button" tabindex="0" class="seat" x="" y="" width="" height="" rx="" ry=""/>{{/available }}
{{^available}}<rect role="button" tabindex="0" class="seat unavailable" x="" y="" width="" height="" rx="" ry=""/>{{/available }}

調整座位表大小

除非您的座位表大小是固定的,否則很難調整包含座位表的 amp-list 大小。amp-list 需要固定尺寸,或使用 layout="fill" (以使用父容器的可用空間)。有兩種方法可以解決此問題

  1. 一旦您知道標頭和頁尾等其他元件使用的空間,請計算頁面上的可用空間。此計算可以在 CSS 中透過使用 calc 表達式來完成,並將其指定為 amp-list 父 div 的 min-height
  2. 在知道頁面版面配置高度時,使用彈性版面配置。

設定 amp-pan-zoom 的樣式

如果使用上一節中描述的方法,amp-pan-zoom 也需要使用 layout="fill"

提示 – 若要在座位表周圍保留一些空白區域,並仍使其成為 Pinch 和縮放區域的一部分

  • 為 SVG 新增包裝 div
  • 新增邊距

如果您沒有包裝 div,而是改為在 SVG 中新增邊界,則不會使邊界成為 Pinch 和縮放區域的一部分。

處理狀態

當使用者點擊不同的座位時,可以使用 amp-state,透過以下方式,追蹤變數中已選取座位的 id

  • 為每個座位新增 amp-bind 表達式,以將選取的座位新增至清單
  • 或將 amp-selector 與動作 on="select:AMP.setState({selectedSeats: event.selectedOptions})" 搭配使用,以便將所有選取的座位新增至清單

雖然第一種方法不需要額外的元件 amp-selector,但它可能會使座位表變得非常慢,因為每個 amp-bind 表達式都會在每次座位選取/取消選取時進行評估。

第二種方法也允許您減少範本將呈現的每個座位的 amp-bind 表達式的重複。

最終 HTML 結構

作為參考,以下是座位表的最終 HTML

<div class="seatmap-container">
  <amp-list layout="fill" src="/json/seats.json" binding="no" items="." single-item noloading>
    <template type="amp-mustache">
      <amp-pan-zoom layout="fill" class="seatmap">
        <amp-selector multiple on="select:AMP.setState({
          selectedSeats: event.selectedOptions
        })" layout="fill">
          <div class="svg-container">
            <svg preserveAspectRatio="xMidYMin slice" viewBox="0 0 {{width}} {{height}}">
            {{#seats}}
              <rect option="{{id}}" role="button"
               tabindex="0" class="seat {{unavailable}}"
              x="{{x}}" y="{{y}}"
              width="{{width}}" height="{{height}}"
              rx="{{rx}}" ry="{{ry}}"/>
            {{/seats}}
            </svg>
          </div>
        </amp-selector>
      </amp-pan-zoom>
    </template>
  </amp-list>
</div>