1. 程式人生 > 其它 >防止重複提交_前端學習(1): 介紹一種防止表單重複提交的方法及2種樣式

防止重複提交_前端學習(1): 介紹一種防止表單重複提交的方法及2種樣式

技術標籤:防止重複提交

準備深入學習一下前端並計劃每週至少寫一篇關於前端的文章。

本文創意來自文章 HTML Forms: How (and Why) to Prevent Double Form Submissions[1],下文是我按照自己的理解進行的轉述。


究其本質,前端防止表單重複提交的方式,大概是給表單繫結一個標識變數,表單提交時將其鎖定、提交成功或失敗後再釋放。對於重複的提交操作,都在提交前判斷標識變數是否鎖定,如果鎖定,則不予提交。


我們把關注點放在樣式展現上(畢竟我是在學習前端),假設表單的初始狀態是這樣的:

0c59f420837e075ad7f4db892ac8758f.png

點選提交後,我們要的效果是把整個表單置灰,並顯示一個 Spinner:

a1a2233ead8b9060e51d4842314417ee.png

因為涉及到表單提交的攔截操作,一些 JavaScript 程式碼是不可少的:

//防止重複提交
document.querySelectorAll('form').forEach((form)=>{
form.addEventListener('submit',(e)=>{
e.preventDefault();

//如果表單提交過,則含有is-submitting這個類
if(form.classList.contains('is-submitting')){
console.info('Successivesubmitsuppressed');
//不再進行後續操作
return;
}

//再發送ajax請求前鎖定表單
form.classList.add('is-submitting');
//ajax();
});
});

整個程式碼比較容易理解,見註釋。

接下來是 css 部分:

初始的表單樣式程式碼按如下定義:

form{
position:relative;
display:inline-block;
}

當 form 在鎖定狀態(is-submitting) 時,加上置灰的背景和 Spinner:

form.is-submitting::after{
position:absolute;
content:'';
top:-0.5em;
right:-0.5em;
left:-0.5em;
bottom:-0.5em;
background:rgba(0,0,0,0.2)url('/spinner.png')no-repeat50%50%/1em1em;
}

結合兩個樣式,可以看到:

  1. form 設定為 relative 定位,是為了服務於之後的鎖定狀態 (::after)。
  2. 四個方位(toprightleftbottom)設定為負值,是為了在覆蓋表單區域的基礎上,再往外延伸 0.5em,這樣更好看一些。
  3. background部分,比較難理解的是 50% 50% / 1em 1em,我查了文件後才知道,它分別表示 background_positionbackground_size (即在本例中是 Spinner 的位置和尺寸)

以上是第一種方式。如果你不喜歡在提交時將整個表單置灰,還可以只置灰 提交 按鈕。

樣式2:僅置灰提交按鈕

這個方案下,JavaScript 部分是不變的,主要是 css 樣式部分有調整。

表單在提交前和提交時,樣式表現分別如下:

34faf60583c184235d6c37d9c376884a.png
提交前
a2d2f99b4ad7fc25c585a8a4b1f3f758.png
提交後

css 程式碼如下:

formbutton[type="submit"]{
position:relative;
overflow:hidden;
background-color:rgba(0,128,0,1);
color:white;
border:0;
padding:0.5em0.7em;
}

form.is-submittingbutton[type="submit"]{
background-color:rgba(0,128,0,0.7);
outline:0;
}

form.is-submittingbutton[type="submit"]::before{
position:absolute;
content:'';
height:0.2em;
left:0;
right:0;
top:0;
background:green;
animation:move1slinearinfinite;
}

@keyframesmove{
0%{
transform:translateX(-100%);
}
100%{
transform:translateX(100%);
}
}

惟一要注意的是,提交按鈕在提交時,用到了動畫 (animation) 來動態展示處理中這個狀態。


好了,新技巧 Get ? 。如果需要檢視 demo,點選「閱讀原文」。

參考資料

[1]

HTML Forms: How (and Why) to Prevent Double Form Submissions: https://www.bram.us/2020/11/04/preventing-double-form-submissions/

- END -