提交表单后或Safari点击返回页面时如何重置amp-states?
问题原因
该问题由浏览器**往返缓存(Back-Forward Cache,简称bfcache)**的机制差异导致:
- 表单提交时你先将
isLoading设为true,之后页面立刻触发跳转,submit-success事件还没来得及执行,重置逻辑就已经失效 - Safari、Firefox会将跳转前的页面完整快照(包括AMP运行时状态、DOM修改结果)存储在bfcache中,点击返回按钮时会直接恢复快照,不会重新初始化AMP的
amp-state,因此isLoading=true的状态被保留 - Chrome的bfcache对AMP状态的恢复逻辑不同,会重新触发AMP初始化流程,因此没有该问题
修复方案(保留amp-state用法)
给表单增加pageshow事件绑定,该事件在页面首次加载、以及从bfcache恢复(点击返回按钮回到页面)时都会触发,直接在该事件中重置isLoading状态即可,修改后的代码如下:
<amp-state id="testState"> <script type="application/json"> { "isLoading": false } </script> </amp-state> <div class="my-class" role="button"> <form id="test" class="buysell-form" action="nextPageUrl" method="GET" target="_top" on=" pageshow: AMP.setState({testState: { isLoading: false }}); submit: AMP.setState({testState: { isLoading: true }}); submit-success: AMP.setState({testState: { isLoading: false }}); submit-error: AMP.setState({testState: { isLoading: false }}); invalid: AMP.setState({testState: { isLoading: false }});" custom-validation-reporting="show-first-on-submit"> <div class="inputs"> <input type="text" class="location-input" title="Enter your city"> <input type="submit" value="My button" [value]="testState.isLoading ? 'Loading...' : 'My button'" class="next-button" [class]="testState.isLoading ? 'next-button disabled' : 'next-button'" [disabled]="testState.isLoading"> </div> </form> </div>
无amp-state的替代方案
直接用原生JS管理按钮状态,完全脱离AMP状态管理,兼容性更强,所有浏览器都能正常运行:
<form id="test" class="buysell-form" action="nextPageUrl" method="GET" target="_top"> <div class="inputs"> <input type="text" class="location-input" title="Enter your city"> <input type="submit" value="My button" id="submitBtn" class="next-button"> </div> </form> <script> const submitBtn = document.getElementById('submitBtn'); const form = document.getElementById('test'); // 提交时修改按钮状态 form.addEventListener('submit', () => { submitBtn.value = 'Loading...'; submitBtn.classList.add('disabled'); submitBtn.disabled = true; }); // 页面显示时(包括从bfcache恢复)重置按钮 window.addEventListener('pageshow', () => { submitBtn.value = 'My button'; submitBtn.classList.remove('disabled'); submitBtn.disabled = false; }); </script>
内容的提问来源于stack exchange,提问作者Антонина
相关产品推荐
相关产品推荐

