
AMP Email 不支持 JavaScript,但可通过 amp-bind 和状态管理实现基于用户选择的动态题干切换;本文详解如何用 amp-state、[hidden] 绑定与 amp-selector 构建可交互的多步问卷流程,并指出常见失效原因及修复方案。
amp email 不支持 javascript,但可通过 `amp-bind` 和状态管理实现基于用户选择的动态题干切换;本文详解如何用 `amp-state`、`[hidden]` 绑定与 `amp-selector` 构建可交互的多步问卷流程,并指出常见失效原因及修复方案。
在 AMP Email 中实现“答完上一题才显示下一题”的交互逻辑,核心在于利用 AMP 的声明式响应式绑定机制替代传统 JS 控制流。由于 Gmail、Yahoo 等主流邮件客户端仅支持有限的 AMP for Email 组件(且禁用脚本执行),你无法使用 React 或原生事件监听器来驱动 DOM 变更——必须完全依赖 amp-bind 的状态驱动渲染。
✅ 正确实现要点
-
启用严格 CSS 模式
邮件客户端可能因样式隔离策略导致 [hidden] 绑定失效。务必在 <html> 标签中添加 data-css-strict 属性:<html ⚡4email data-css-strict>
-
用 amp-state 管理当前题号与答案 初始化状态时明确设置起始题号,并为每道题预留独立字段(便于后续提交):
<amp-state id="formState"> <script type="application/json"> { "currentQuestion": 1, "answer1": "", "answer2": "", "answer3": "", "answer4": "", "answer5": "" } </script> </amp-state> -
使用 amp-selector 触发题号切换
amp-selector 是邮件中唯一支持“点击即更新状态”的交互组件(<button onclick="..."> 无效)。每个选项对应一道题,通过 on="select:AMP.setState(...)" 切换 currentQuestion:<amp-selector layout="container" name="navSelector" keyboard-select-mode="focus"> <div option="1" selected="selected" role="button" tabindex="0">Q1</div> <div option="2" role="button" tabindex="0">Q2</div> <div option="3" role="button" tabindex="0">Q3</div> <!-- ... --> </amp-selector>
-
用 [hidden] 动态控制题干显隐
每个 <section> 通过绑定表达式控制是否隐藏。注意:不能用 amp-mustache 包裹多个 <section>(模板仅用于服务端渲染静态内容,不参与运行时绑定)——所有题干需写在模板外,直接使用 [hidden]:<!-- Question 1 --> <section [hidden]="formState.currentQuestion !== 1"> <label>1. Would you love to partner with KNOTOPIAN?</label> <input type="date" name="question1" on="change:AMP.setState({formState: {currentQuestion: 2, answer1: event.value}})" /> </section> <!-- Question 2 --> <section [hidden]="formState.currentQuestion !== 2"> <label>2. Would you give us a chance to display our portfolio?</label> <input type="date" name="question2" on="change:AMP.setState({formState: {currentQuestion: 3, answer2: event.value}})" /> </section> <!-- 后续题目依此类推 --> -
提交按钮条件显示
仅当到达最后一题时显示提交按钮,并确保 type="submit" 与 form 关联:<button type="submit" [hidden]="formState.currentQuestion !== 5" class="submit-btn" > Submit All Answers </button>
⚠️ 关键注意事项
-
amp-bind 在 Gmail/Yahoo 中需显式启用:确保 <head> 中引入了 amp-bind 扩展脚本,且未被 CDN 缓存旧版本:
<script async custom-element="amp-bind" src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>
- 禁止使用 event.targetOption:amp-selector 的 event.targetOption 在部分客户端(如 Gmail iOS)存在兼容性问题,推荐改用预设 option 值 + select 事件直接赋值。
- 输入框需绑定 on="change:..." 而非 on="input:...":邮件客户端对实时输入事件支持极弱,change(失焦或回车确认)更可靠。
- 服务端接收时需处理空值:用户可能跳过某题,后端应允许 question2 等字段为空。
- 测试务必使用真实环境:本地预览或浏览器打开 .html 文件无法模拟邮件客户端限制,必须通过 AMP Email Playground 或实际发送至 Gmail 测试。
✅ 完整可运行片段(精简版)
<html ⚡4email data-css-strict>
<head>
<meta charset="utf-8">
<script async src="https://cdn.ampproject.org/v0.js"></script>
<script async custom-element="amp-bind" src="https://cdn.ampproject.org/v0/amp-bind-0.1.js"></script>
<script async custom-element="amp-form" src="https://cdn.ampproject.org/v0/amp-form-0.1.js"></script>
<script async custom-element="amp-selector" src="https://cdn.ampproject.org/v0/amp-selector-0.1.js"></script>
<style amp-custom>
section { margin: 20px 0; }
.submit-btn { background: #4CAF50; color: white; border: none; padding: 12px 24px; }
</style>
</head>
<body>
<form action-xhr="https://myapp/api/receiveEmail" method="POST">
<amp-state id="formState">
<script type="application/json">{"currentQuestion": 1}</script>
</amp-state>
<!-- 导航选择器 -->
<amp-selector name="nav" layout="container" on="select:AMP.setState({formState: {currentQuestion: event.targetOption}})">
<div option="1" selected>1</div>
<div option="2">2</div>
<div option="3">3</div>
<div option="4">4</div>
<div option="5">5</div>
</amp-selector>
<!-- 题干区域 -->
<section [hidden]="formState.currentQuestion !== 1">
<h3>Question 1</h3>
<input type="date" name="q1" on="change:AMP.setState({formState: {currentQuestion: 2}})">
</section>
<section [hidden]="formState.currentQuestion !== 2">
<h3>Question 2</h3>
<input type="date" name="q2" on="change:AMP.setState({formState: {currentQuestion: 3}})">
</section>
<!-- ... Q3–Q5 类似 -->
<button type="submit" [hidden]="formState.currentQuestion !== 5" class="submit-btn">
Submit
</button>
</form>
</body>
</html>通过以上结构,你就能在严格受限的 AMP Email 环境中,构建出真正可用的分步式交互表单——无需妥协用户体验,也无需绕过 AMP 规范。记住:状态即 UI,绑定即逻辑,约束即保障。

















