2.4 表单对象过滤:专项活检 凌晨的值班群里最常出现的截图,是一张"什么都没填却提交成功"的表单。表单控件值得从选择器里单独辟出一节,因为它们的要害不在位置而在状态:勾没勾上、禁没禁用、选中了哪一项。给标本页补一块登记表单,这一节所有活检都在它上面做。 本节摘要:表单过滤分两族——类型族按控件种类圈人( 、 、 、 等),状态族按勾选与可用状态留人( 、 、 、 )。前者是类型普查,后者是状态活检,表单校验几乎是每一段前端代码的必经之路。 给标本页添一块登记表 类型族:先按控件种类圈出普查范围 是 jQuery 自造的伞形选择器,原生没有对应物——它把 、 、 、 一网打尽,做"整表控件统一处理"时最好用。类型族其余成员与 HTML 的 属性一一对应,没什么悬念;
凌晨的值班群里最常出现的截图,是一张"什么都没填却提交成功"的表单。表单控件值得从选择器里单独辟出一节,因为它们的要害不在位置而在状态:勾没勾上、禁没禁用、选中了哪一项。给标本页补一块登记表单,这一节所有活检都在它上面做。
本节摘要:表单过滤分两族——类型族按控件种类圈人(
:input、:text、:button、:checkbox等),状态族按勾选与可用状态留人(:checked、:selected、:disabled、:enabled)。前者是类型普查,后者是状态活检,表单校验几乎是每一段前端代码的必经之路。
<form id="register" class="panel"> <h2 class="panel-title">陪护登记</h2> <input type="text" name="guest" class="txt" placeholder="姓名"> <input type="text" name="phone" class="txt" placeholder="电话"> <select name="bed"> <option value="">请选择床位</option> <option value="a">三号床</option> <option value="b">五号床</option> </select> <label><input type="checkbox" name="agree"> 已阅读陪护须知</label> <button type="submit" id="submit-btn" class="btn">提交登记</button> </form>
$('#register :input').length; // 5:所有表单控件,包括 select、button $('#register :text').length; // 2:仅文本输入框 $('#register :checkbox').length; // 1 $('#register :button').length; // 1:type 为 button 或标签为 button 的控件
:input 是 jQuery 自造的伞形选择器,原生没有对应物——它把 input、select、textarea、button 一网打尽,做"整表控件统一处理"时最好用。类型族其余成员与 HTML 的 type 属性一一对应,没什么悬念;要注意 :text 只匹配 type="text" 的输入框,没有写 type 属性的旧式输入框在不同版本里行为有差异,写严谨的页面应当显式声明 type。
状态族的成员屈指可数,却是表单校验的全部主力:
// 勾选类:复选框与单选框 $('input[name="agree"]:checked').length; // 1 表示须知已勾选 // 选中类:下拉框当前选中的选项 $('select[name="bed"] option:selected').text(); // 例如 '请选择床位' // 可用性:被禁用与可用的控件 $('#register :disabled').length; // 0:目前没有禁用项 $('#register :enabled').length; // 5

矩阵里最值得停下来的是 :selected 一行:jQuery 叫 :selected,CSS 标准叫 option:checked,语义相同、写法不同。见到老代码里两个写法混用,先别当成 bug。
把状态族串成一次真实的提交拦截——按钮初始禁用,三项检查全部通过才放行:
$(function () { var $form = $('#register'); var $btn = $('#submit-btn'); function checkup() { var okName = $form.find('input[name="guest"]').val().trim() !== ''; var okBed = $form.find('option:selected').val() !== ''; var okAgree = $form.find(':checkbox:checked').length === 1; $btn.prop('disabled', !(okName && okBed && okAgree)); } // 控件状态一变就复检:input 事件在 4.3 节细讲,这里先照抄 $form.on('input change', checkup); checkup(); // 初次体检:让按钮一开始就是禁用态 });
逐步走一遍。背景:裸表单在空数据时也能点提交,服务端就要替前端兜底。操作:checkup 函数把三项要求各自翻译成状态族查询,全过才解开按钮。结果:姓名未填或未选床位或未勾须知时,按钮按下去毫无反应。解读:拦截逻辑全部收口在一个函数里,任何控件变化都触发同一次复检,不存在"改了这里忘了那里"。变式:如果要求"至少留一个联系方式",把电话框加进检查列表即可——活检刀够用,逻辑不必重写。
:input 一网打尽,状态活检靠 :checked、:selected、:disabled。:selected 与原生 option:checked 同义异名,迁移时留心。:input 是 jQuery 方言,原生要用四个标签选择器自己拼并集。.text() 返回空串,恰好可以当校验条件用。至此四把定位刀全部出鞘。下一章把镜头拉近:选中之后,怎么沿着 DOM 树继续走、把病灶档案改掉、把缺失的组织补上。