收藏按鈕
簡介
此範例示範如何在 AMP 中實作收藏/讚/書籤按鈕。我們的實作方式
- 會根據使用者是否已按讚項目來顯示正確的圖示。無論 AMP 是從 AMP 快取或原始來源提供,此方式都適用。
- 在非同步載入目前狀態時顯示預留位置。
- 在請求失敗時 (例如使用者離線時) 回溯至原始狀態並顯示錯誤訊息。
設定
我們使用 amp-list
元件來動態呈現收藏按鈕的初始狀態。
<script async custom-element="amp-list" src="https://cdn.ampproject.org/v0/amp-list-0.1.js"></script>
amp-list
需要 mustache 元件。
<script async custom-template="amp-mustache" src="https://cdn.ampproject.org/v0/amp-mustache-0.2.js"></script>
我們需要 amp-form
來提交收藏請求。
<script async custom-element="amp-form" src="https://cdn.ampproject.org/v0/amp-form-0.1.js"></script>
amp-bind
讓我們能夠在提交表單時動態變更按鈕狀態。
<script async custom-element="amp-bind" src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>
管理狀態
我們使用 amp-state
從 JSON 端點初始化按鈕狀態。由於我們使用 Cookie 來識別使用者,因此需要新增 credentials="include"
屬性。
<amp-state id="favorite" credentials="include" src="https://amp.dev.org.tw/documentation/examples/interactivity-dynamic-content/favorite_button/favorite">
</amp-state>
簡易收藏按鈕
按鈕嵌入在 amp-list
內,讓我們能夠根據使用者是否已按讚項目來動態呈現按鈕。在範本內,我們使用 mustache 的隱含迭代器 .
來存取 /favorite
端點傳回的布林值:{{#.}}heart-fill{{/.}}
。
我們也在 amp-list
內使用 placeholder
屬性宣告預留位置圖示,此圖示會在 amp-list
載入時顯示。
當使用者按下收藏按鈕時,會發生以下幾件事
- 當使用者按下按鈕時,表單會傳送切換請求。
- 我們實作了樂觀 UX,會在按下按鈕時立即更新按鈕狀態。
- 如果表單提交失敗 (
submit-error:...
),我們會將收藏狀態還原為原始版本,並顯示錯誤訊息 (favorite-failed-message.show
)。 - 我們會隱藏任何現有的錯誤訊息 (
favorite-failed-message.hide
)。
<form class="favorite-button" method="post" action-xhr="https://amp.dev.org.tw/documentation/examples/interactivity-dynamic-content/favorite_button/favorite" target="_top" on="submit:AMP.setState({
favorite: !favorite
}),
favorite-failed-message.hide;
submit-error:AMP.setState({
favorite: !favorite
}),
favorite-failed-message.show">
<amp-list width="56" height="56" credentials="include" items="." single-item src="https://amp.dev.org.tw/documentation/examples/interactivity-dynamic-content/favorite_button/favorite" binding="always">
<template type="amp-mustache">
<input type="submit" class="{{#.}}heart-fill{{/.}}{{^.}}heart-border{{/.}}" [class]="favorite ? 'heart-fill' : 'heart-border'" value aria-label="Favorite Toggle">
</template>
<div placeholder>
<input type="submit" disabled class="heart-loading" value aria-label="favorite placeholder">
</div>
</amp-list>
</form>
簡易的 Snackbar,會在表單提交失敗時顯示。
<div id="favorite-failed-message" hidden>Error: Could not favorite.
<div on="tap:favorite-failed-message.hide" tabindex="0" role="button">CLOSE</div>
</div>
具計數器的收藏按鈕
這是先前範例的更精緻版本,也包含收藏數。我們的JSON 端點傳回兩個值:value
和 count
。
<amp-state id="favoriteWithCount" credentials="include" src="https://amp.dev.org.tw/documentation/examples/interactivity-dynamic-content/favorite_button/favorite-with-count">
</amp-state>
實作方式與先前的範例類似,但也會在按一下按鈕時更新計數
AMP.setState({ ..., count: favoriteWithCount.count + (favoriteWithCount.value ? -1 : 1) })
我們使用暫時變數 previousFavoriteWithCount
來儲存先前的值,以便在表單提交失敗時能夠還原按鈕狀態。
<form class="favorite-button" method="post" action-xhr="https://amp.dev.org.tw/documentation/examples/interactivity-dynamic-content/favorite_button/favorite-with-count" target="_top" on="submit:AMP.setState({
previousFavoriteWithCount: favoriteWithCount,
favoriteWithCount: {
value: !favoriteWithCount.value,
count: favoriteWithCount.count + (favoriteWithCount.value ? -1 : 1),
}
}),
favorite-failed-message.hide;
submit-error:AMP.setState({
value: !favoriteWithCount.value,
favoriteWithCount: previousFavoriteWithCount.count
}),
favorite-failed-message.show">
<amp-list width="200" height="56" credentials="include" items="." single-item noloading src="https://amp.dev.org.tw/documentation/examples/interactivity-dynamic-content/favorite_button/favorite-with-count" binding="always">
<template type="amp-mustache">
<div class="favorite-container">
<input type="submit" class="{{#value}}heart-fill{{/value}}{{^value}}heart-border{{/value}}" [class]="favoriteWithCount.value ? 'heart-fill' : 'heart-border'" value aria-label="Favorite Toggle">
<div class="favorite-count" [text]="favoriteWithCount.count ? favoriteWithCount.count : ''">{{count}}</div>
</div>
</template>
<div placeholder>
<div class="favorite-container">
<input type="submit" disabled class="heart-loading" value aria-label="favorite placeholder">
<div class="favorite-count loading">0</div>
</div>
</div>
</amp-list>
</form>
如果本頁面的說明未能涵蓋您的所有問題,歡迎隨時與其他 AMP 使用者交流,討論您的確切使用案例。
前往 Stack Overflow 有未說明的特色功能?AMP 專案大力鼓勵您的參與和貢獻!我們希望您能成為我們開放原始碼社群的長期參與者,但我們也歡迎您針對自己特別關注的問題做出一次性的貢獻。
在 GitHub 上編輯範例