這次先準備一份學習挑戰報名表,裡面包含暱稱、電子郵件、想學的內容和同意規範:
<form id="signup-form" novalidate>
<label>暱稱
<input name="nickname" required minlength="2">
</label>
<label>電子郵件
<input name="email" type="email" required>
</label>
<fieldset>
<legend>想學的內容</legend>
<label><input name="topics" type="checkbox" value="DOM"> DOM</label>
<label><input name="topics" type="checkbox" value="事件"> 事件</label>
</fieldset>
<label>
<input name="terms" type="checkbox" required>
我同意學習規範
</label>
<button type="submit">送出報名</button>
</form>
<div class="message"></div>
每個欄位都有name,後面的 JavaScript會使用這個名稱取得資料。例如暱稱欄位的name是nickname,兩個想學內容的核取方塊則使用相同的topics。
首先選取整份表單,再從表單中找到暱稱欄位。欄位目前的內容可以透過value取得:
const form = document.querySelector("#signup-form");
const nicknameInput = form.elements.nickname;
console.log(nicknameInput.value);
form.elements會按照欄位的name尋找控制項。輸入暱稱和電子郵件後,可以分別取得兩個值:
const nickname = form.elements.nickname.value;
const email = form.elements.email.value;
如果要一次收集整份表單,可以建立FormData。下面的form就是前面選取的#signup-form:
const data = new FormData(form);
console.log(data.get("nickname"));
console.log(data.get("email"));
console.log(data.has("terms"));
FormData按照欄位的name收集資料,不是id。get()取得第一個同名欄位,has()檢查欄位是否存在。多個核取方塊使用相同名稱時,可以使用getAll()取得所有勾選值:
const topics = data.getAll("topics");
console.log(topics);
想查看整份資料,可以走訪entries():
for (const [name, value] of data.entries()) {
console.log(name, value);
}
前面的讀值程式會放在表單的submit事件中,等使用者填寫完成並送出後再執行。使用者點擊送出按鈕或在輸入框按 Enter,都會進入同一個事件。
form.addEventListener("submit", (event) => {
event.preventDefault();
});
preventDefault()停止重新載入頁面的預設行為,讓 JavaScript 能留在目前畫面檢查資料。
HTML提供required、minlength和type="email"等原生規則。checkValidity()只回傳是否通過,reportValidity()則會另外顯示瀏覽器的提示:
if (!form.checkValidity()) {
form.reportValidity();
return;
}
實作另外建立errors陣列檢查自訂條件,再用classList.toggle()切換錯誤樣式。原生驗證適合基本格式,自訂驗證則處理網站自己的規則;正式資料送到後端後仍要再次檢查。