JavaScript 表单

张开发
2026/4/17 7:23:22 15 分钟阅读

分享文章

JavaScript 表单
JavaScript 表单 (Forms) 学习笔记在 Web 开发中表单是用户与服务器交互的核心入口。JavaScript 赋予了表单强大的动态处理能力从实时验证到无刷新提交极大地提升了用户体验。一、HTML 表单基础回顾在深入 JS 之前先回顾一下 HTML 表单的基本结构formidmyFormaction/submitmethodPOSTlabelforusername用户名:/labelinputtypetextidusernamenameusernamerequiredlabelforemail邮箱:/labelinputtypeemailidemailnameemaillabelforage年龄:/labelinputtypenumberidagenameagemin1max120labelinputtypecheckboxnameagreevalueyes同意条款/labelselectnamecountryoptionvaluecn中国/optionoptionvalueus美国/option/selectbuttontypesubmit提交/button/form二、获取表单元素1. 通过document.getElementById或querySelectorconstformdocument.getElementById(myForm);constusernameInputdocument.getElementById(username);constemailInputdocument.querySelector(#myForm input[typeemail]);2. 通过form.elements属性 (推荐)form.elements返回一个包含表单内所有控件的集合可以通过name属性直接访问。constformdocument.getElementById(myForm);// 直接通过 name 访问constusernameform.elements.username;constemailform.elements.email;// 访问单选/复选框组 (返回 NodeList)constcheckboxesform.elements.agree;3. 遍历表单控件for(leti0;iform.elements.length;i){constelementform.elements[i];console.log(element.name,element.value);}三、获取和设置值1. 获取值 (value)// 文本、密码、数字、隐藏域constnameform.elements.username.value;// 单选框 (Radio) - 需要遍历找到被选中的constgenderArray.from(form.elements.gender).find(elel.checked)?.value;// 复选框 (Checkbox) - 单个constagreeform.elements.agree.checked;// 返回布尔值// 下拉框 (Select)constcountryform.elements.country.value;// 多选下拉框 (multiple)constselectedOptionsArray.from(form.elements.country.selectedOptions).map(optopt.value);2. 设置值form.elements.username.value张三;form.elements.email.valuezhangsanexample.com;form.elements.agree.checkedtrue;// 勾选复选框form.elements.country.valueus;// 选中下拉框四、表单验证 (Validation)JavaScript 提供了两种验证方式HTML5 原生验证和自定义验证。1. HTML5 原生验证 API利用required,pattern,min,max等属性配合 JS API 进行交互。常用属性与方法属性/方法描述checkValidity()返回true如果表单/元素有效否则falsevalidity返回ValidityState对象包含详细错误状态validationMessage浏览器默认的验证错误提示信息setCustomValidity(msg)设置自定义错误信息 (传入空字符串清除)reportValidity()触发浏览器默认验证 UI (显示气泡提示)validity对象常用属性valueMissing: 必填项为空typeMismatch: 类型不匹配 (如 email 格式不对)tooShort/tooLong: 长度限制rangeUnderflow/rangeOverflow: 数值范围限制patternMismatch: 正则不匹配customError: 调用了setCustomValidity且传入了非空字符串示例自定义验证逻辑constemailInputdocument.getElementById(email);emailInput.addEventListener(input,(){constemailemailInput.value;// 简单的邮箱正则constemailRegex/^[^\s][^\s]\.[^\s]$/;if(email!emailRegex.test(email)){// 设置自定义错误emailInput.setCustomValidity(邮箱格式不正确);}else{// 清除自定义错误emailInput.setCustomValidity();}});// 提交时触发验证document.getElementById(myForm).addEventListener(submit,(e){if(!emailInput.checkValidity()){e.preventDefault();// 阻止提交emailInput.reportValidity();// 显示浏览器默认提示气泡}});2. 自定义样式验证结合 CSS 伪类:valid和:invalid实现实时样式反馈。input:invalid{border-color:red;}input:valid{border-color:green;}/* 避免输入时一直报错只在用户输入后或提交时显示 */input:not(:placeholder-shown):invalid{border-color:red;}五、表单事件事件触发时机用途submit表单提交时拦截提交、验证数据、AJAX 提交input输入值变化时实时验证、自动保存、动态计算change元素失去焦点且值改变时下拉框选择、复选框切换focus/blur获得/失去焦点显示/隐藏提示、自动聚焦invalid验证失败时自定义错误提示 UI示例实时验证与提交拦截constformdocument.getElementById(myForm);constusernamedocument.getElementById(username);// 实时验证username.addEventListener(input,(){if(username.value.length3){username.setCustomValidity(用户名至少3个字符);}else{username.setCustomValidity();}});// 提交处理form.addEventListener(submit,(e){e.preventDefault();// 阻止默认提交if(!form.checkValidity()){form.reportValidity();// 显示所有错误return;}// 获取数据constformDatanewFormData(form);constdataObject.fromEntries(formData.entries());console.log(提交数据:,data);// 模拟 AJAX 提交// fetch(/api/submit, { method: POST, body: JSON.stringify(data) ... })});六、FormData 对象FormData是处理表单数据的利器它可以直接从表单元素构建键值对支持文件上传且能自动处理编码。1. 创建 FormDataconstformdocument.getElementById(myForm);constformDatanewFormData(form);2. 获取数据// 获取单个值 (如果有多个同名控件只返回第一个)constnameformData.get(username);// 获取所有同名值 (如多选框)consthobbiesformData.getAll(hobby);// 检查是否存在consthasEmailformData.has(email);// 遍历所有数据for(const[key,value]offormData.entries()){console.log(key,value);}3. 修改数据formData.append(token,abc123);// 追加formData.set(username,NewName);// 设置/覆盖formData.delete(email);// 删除4. 发送数据 (Fetch API)constformdocument.getElementById(myForm);constformDatanewFormData(form);fetch(/api/submit,{method:POST,body:formData// 浏览器会自动设置 Content-Type: multipart/form-data}).then(responseresponse.json()).then(dataconsole.log(Success:,data)).catch(errorconsole.error(Error:,error));七、文件上传1. 获取文件inputtypefileidfileInputmultipleconstfileInputdocument.getElementById(fileInput);constfilesfileInput.files;// FileList 对象if(files.length0){constfilefiles[0];console.log(file.name,file.size,file.type);// 读取文件内容 (FileReader)constreadernewFileReader();reader.onload(e){console.log(文件内容:,e.target.result);};reader.readAsDataURL(file);// 或 readAsText, readAsArrayBuffer}2. 上传文件使用FormData上传文件非常简单constfileInputdocument.getElementById(fileInput);constformDatanewFormData();formData.append(avatar,fileInput.files[0]);fetch(/api/upload,{method:POST,body:formData});八、高级技巧与最佳实践1. 禁用/启用表单// 禁用整个表单form.disabledtrue;// 禁用单个控件form.elements.username.disabledtrue;2. 重置表单form.reset();// 重置为 HTML 默认值3. 自动聚焦window.onload(){form.elements.username.focus();};4. 防止重复提交letisSubmittingfalse;form.addEventListener(submit,(e){if(isSubmitting){e.preventDefault();return;}isSubmittingtrue;constsubmitBtnform.querySelector(button[typesubmit]);submitBtn.disabledtrue;submitBtn.textContent提交中...;// 模拟请求setTimeout((){isSubmittingfalse;submitBtn.disabledfalse;submitBtn.textContent提交;},2000);});5. 序列化表单为 JSONfunctionserializeForm(form){constformDatanewFormData(form);constobj{};formData.forEach((value,key){if(obj[key]){if(!Array.isArray(obj[key])){obj[key][obj[key]];}obj[key].push(value);}else{obj[key]value;}});returnobj;}constdataserializeForm(form);console.log(JSON.stringify(data));九、总结功能核心 API / 方法获取元素form.elements,querySelector获取/设置值.value,.checked,.selectedIndex验证checkValidity(),validity,setCustomValidity()事件submit,input,change,invalid数据处理FormData,Object.fromEntries()文件上传FileList,FileReader,FormData.append()最佳实践始终验证前端验证提升体验后端验证保证安全。使用FormData处理表单数据最方便、最标准的方式。利用 HTML5 属性required,type,pattern能减少大量 JS 代码。用户体验提供清晰的错误提示禁用提交按钮防止重复提交。无障碍 (A11y)确保label与input正确关联错误信息可被屏幕阅读器读取。掌握这些知识你就能构建出既美观又健壮的交互式表单

更多文章