AMP
  • 网站

收藏按钮

简介

此示例演示如何在 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.org.cn/documentation/examples/interactivity-dynamic-content/favorite_button/favorite">
</amp-state>

简单的收藏按钮

该按钮嵌入在 amp-list 中,这使我们能够根据用户是否已喜欢某些内容来动态渲染按钮。在模板内部,我们使用 mustache 的隐式迭代器 . 来访问我们的 /favorite 端点返回的布尔值:{{#.}}heart-fill{{/.}}

我们还使用 placeholder 属性在 amp-list 中声明一个占位符图标,该图标在 amp-list 加载时显示。

当用户按下收藏按钮时,会发生以下几件事:

  • 当用户按下按钮时,表单会发送切换请求。
  • 我们实现了一个乐观的 UX,当按下按钮时,它将立即更新按钮状态。
  • 如果表单提交失败 (submit-error:...),我们将收藏状态恢复到原始版本,并显示错误消息 (favorite-failed-message.show)。
  • 我们隐藏任何现有的错误消息 (favorite-failed-message.hide)。
<form class="favorite-button" method="post" action-xhr="https://amp.org.cn/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.org.cn/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 端点 返回两个值:valuecount

<amp-state id="favoriteWithCount" credentials="include" src="https://amp.org.cn/documentation/examples/interactivity-dynamic-content/favorite_button/favorite-with-count">
</amp-state>

实现方式与先前的示例类似,但在单击按钮时也会更新计数。

AMP.setState({
  ...,
  count: favoriteWithCount.count + (favoriteWithCount.value ? -1 : 1)
})

我们使用临时变量 previousFavoriteWithCount 来存储先前的值,以便能够在表单提交失败时恢复按钮状态。

0
<form class="favorite-button" method="post" action-xhr="https://amp.org.cn/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.org.cn/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 上编辑示例