- 前端
【免费下载链接】form
jQuery Form Plugin
本篇基于 jQuery Form Plugin 的文档 docs/form-fields.md 展开,系统讲解插件中两个面向“字段集合”的工具方法:fieldValue(获取字段当前值)与fieldSerialize(将表单的一部分序列化为查询字符串)。读完本文,你不仅掌握这两个方法的标准用法与successful参数的语义,还能结合 src/jquery.form.js 的源码实现与 test/test.js 中的测试断言,准确预测各种控件(checkbox、radio、select-multiple 等)在不同状态下的返回值与序列化结果,并在局部提交、局部取数等场景中放心使用它们。
方法定位:fieldValue 与 fieldSerialize 在插件 API 中的角色
jQuery Form Plugin 的核心目标是把普通 HTML 表单升级为可 AJAX 提交(README.md 中的ajaxForm/ajaxSubmit)。围绕表单数据处理,插件提供了几个层次的序列化/取值方法,理解它们的分工是正确使用本文两个方法的前提:
| 方法 | 作用对象 | 返回值 | 说明 |
|---|---|---|---|
formSerialize | 整个<form>元素 | 查询字符串(name1=value1&name2=value2) | 整个表单序列化 |
fieldSerialize | 任意字段元素集合(jQuery 对象) | 查询字符串 | 只序列化选中的一部分字段 |
fieldValue | 任意字段元素集合(jQuery 对象) | 数组(始终返回数组) | 只取值的“原料”,不做编码 |
resetForm/clearForm/clearFields | form / 字段集合 | jQuery 对象 | 重置与清空 |
与 docs/api.md 中的 API 描述一致:fieldSerialize返回 String,fieldValue返回数组,二者都不可链式调用。它们的关键差异在于粒度——formSerialize面向表单整体,而fieldSerialize与fieldValue面向“匹配集”内的字段子集,这正是文档开篇所强调的场景:“This is useful when you need to process only certain fields.”
从源码调用链看,fieldValue并不只是独立的工具方法:formToArray(整表序列化的底层实现)在处理每个普通字段时,内部正是调用$.fieldValue(el, true)来取值的(见 src/jquery.form.js)。也就是说,ajaxForm/ajaxSubmit提交时收集到的数据,其取值规则与本文讨论的规则完全同源——理解fieldValue的语义,也就理解了插件提交数据的底层行为。
fieldValue:获取字段当前值
基本用法
fieldValue用于读取匹配集中字段元素的当前值。文档给出的典型示例是取出 id 为myForm的表单中密码输入框的值:
var pwd = $('#myForm :password').fieldValue()[0];必须牢记的契约是:该方法始终返回数组。无法确定有效值时返回空数组,否则包含一个或多个值:
// 匹配到一个 text 输入框,值为 'abc' $('#myForm :text').fieldValue(); // => ['abc'] // 匹配到没有任何选中项的 checkbox 集合 $('#myUncheckedBoxes').fieldValue(); // => []docs/api.md 中的示例同样演示了这一取法:
// get the value of the password input var value = $('#myFormId :password').fieldValue(); alert('The password is: ' + value[0]);返回值随控件类型而不同
结合源码注释(src/jquery.form.js)给出的示例场景,可以归纳出各控件类型在“成功控件”模式下的返回形态:
// 两个同 name 的 text 输入框:始终返回各自的值(未输入则为 '') var v = $('input[type=text]').fieldValue(); // 未输入时 v === ['',''];输入 'foo' 和 'bar' 时 v === ['foo','bar'] // 未勾选的 checkbox 集合:空数组 var v = $('input[type=checkbox]').fieldValue(); // 两个都勾选时 v === ['B1','B2'] // radio 组:只有被选中的那一个返回 var v = $('input[type=radio]').fieldValue(); // 均未选中时 v === [];选中第一个时 v === ['C1']对于select元素:单选select返回单个选中项的 value;带multiple的select返回所有被选中且未禁用选项的 value 数组;若没有任何选项被选中(selectedIndex === -1),则视为无效值(返回null,最终被fieldValue过滤掉)。对于 textarea、text、hidden、password 等常规控件,返回的是$(el).val()的字符串值。
successful 参数与“成功控件”语义
fieldValue接受一个可选参数successful,控制“字段是否必须处于成功控件(successful control)状态才算有效”。默认值为true,即与浏览器原生构建表单数据集时的行为保持一致:未勾选的 checkbox、未被点中的 submit 按钮、无 name 的控件、disabled 的控件等都不会产生值。
文档中的演示:对一个未勾选的 checkbox:
// value will be an empty array if checkbox is not checked: var value = $('#myUncheckedCheckbox').fieldValue(); // value.length == 0但如果你确实想在 checkbox 未勾选时仍然拿到它的value属性,可以显式传入false:
// value will hold the checkbox value even if it's not checked: var value = $('#myUncheckedCheckbox').fieldValue(false); // value.length == 1源码(src/jquery.form.js)对这一判定给出了完整依据。$.fieldValue(el, successful)在未显式传参时将successful置为true,随后执行如下过滤——命中任意一条即返回null:
if (typeof successful === 'undefined') { successful = true; } if (successful && (!n || el.disabled || t === 'reset' || t === 'button' || (t === 'checkbox' || t === 'radio') && !el.checked || (t === 'submit' || t === 'image') && el.form && el.form.clk !== el || tag === 'select' && el.selectedIndex === -1)) { return null; }翻译成规则表(successful === true时生效):
| 判定条件 | 结果 |
|---|---|
无name属性 | 无值(null) |
控件disabled | 无值 |
type为reset或button | 无值 |
checkbox/radio且未checked | 无值 |
submit/image且不是本次点击的按钮(form.clk !== el) | 无值 |
select且selectedIndex === -1(无任何选中项) | 无值 |
这解释了两个常见“意外”:其一,reset按钮的 value 永远取不到;其二,fieldValue作用在全部 submit 按钮上时,只有模拟“被点击”的那个才有效——这与formToArray中对form.clk(被点击的图片/提交按钮坐标)的特殊处理相呼应。
源码实现细节:合并、过滤与换行规范化
jQuery 方法层$.fn.fieldValue的实现(src/jquery.form.js)遍历匹配集中的每个元素,调用底层$.fieldValue并按类型合并结果:
$.fn.fieldValue = function(successful) { for (var val = [], i = 0, max = this.length; i < max; i++) { var el = this[i]; var v = $.fieldValue(el, successful); if (v === null || typeof v === 'undefined' || (v.constructor === Array && !v.length)) { continue; // 无效值(null/undefined/空数组)直接跳过 } if (v.constructor === Array) { $.merge(val, v); // select-multiple 的数组结果并入总数组 } else { val.push(v); } } return val; };要点有二:
- 无效值被静默过滤:单个元素返回
null、undefined或空数组时直接continue,所以“始终返回数组”且数组里不会出现空槽。 - 多值控件展开合并:一个
select multiple产生的数组会被$.merge平铺进总结果,多个 checkbox/radio 的值按元素顺序依次追加。
对 select 分支,源码(src/jquery.form.js)区分了单选与多选:单选只遍历被选中的一项并直接返回其 value;多选则遍历全部选项,收集“selected且未disabled”的选项。其中还有一段针对旧版 IE 的兜底:当选项未显式指定value属性时回退使用op.text。
对除 select 外的控件,最终取值为(src/jquery.form.js):
return $(el).val().replace(rCRLF, '\r\n');其中rCRLF = /\r?\n/g(定义于 src/jquery.form.js)。这个替换的作用是把 textarea 中的换行统一规范为 CRLF,避免在 Windows 文本域中产生的\r\n与类 Unix 环境产生的\n混用时出现“双回车”问题——这是从源码结构看一个容易被忽略但很实用的细节。
fieldSerialize:只序列化表单的一部分
基本用法
fieldSerialize把匹配集中的字段元素序列化为查询字符串,格式为name1=value1&name2=value2。当只需要提交/处理表单中的某些字段时,它比formSerialize更合适。文档示例——只序列化表单中的 text 输入:
var queryString = $('#myForm :text').fieldSerialize();docs/api.md 与 README.md 给出的另一种典型用法是按 CSS 类名选取“特殊字段组”:
var queryString = $('#myFormId .specialFields').fieldSerialize();序列化结果可以直接交给$.get/$.post/$.ajax完成部分字段提交,而无需触发整个表单。
序列化规则:无 name 即跳过,数组展开,$.param 编码
源码实现(src/jquery.form.js)非常直白:
/** * Serializes all field elements in the jQuery object into a query string. * This method will return a string in the format: name1=value1&name2=value2 */ $.fn.fieldSerialize = function(successful) { var a = []; this.each(function() { var n = this.name; if (!n) { return; // 无 name 的字段直接跳过 } var v = $.fieldValue(this, successful); if (v && v.constructor === Array) { for (var i = 0, max = v.length; i < max; i++) { a.push({name: n, value: v[i]}); // 多值控件展开为多个同名键 } } else if (v !== null && typeof v !== 'undefined') { a.push({name: this.name, value: v}); } }); // hand off to jQuery.param for proper encoding return $.param(a); };三个规则值得强调:
- 无
name的字段被静默跳过,不会在结果中留下null=...之类的脏数据; - 多值控件(checkbox 组、select multiple)展开为多个同名键值对,例如两个勾选的
F复选框会产出F=8&F=10; - 编码完全委托给
jQuery.param,保证空格、中文等特殊字符被正确 URL 编码。这与formSerialize的做法一致($.param(this.formToArray(semantic)),见 src/jquery.form.js)。
与fieldValue一样,fieldSerialize也接受successful参数,默认行为只序列化“成功控件”。二者的关系可以理解为:fieldSerialize=fieldValue的取值规则 + 同名键展开 +$.param编码。
测试套件中的行为验证
仓库的 QUnit 测试(test/test.js)围绕 test/test.html 中的隐藏测试表单#fieldTest对这两个方法做了成对断言,非常适合用来核对心智模型:
<!-- test/test.html 中的 #fieldTest 表单(节选) --> <select name="A">...(选中 value="1") <select name="B" multiple="multiple">...(选中 3 和 4) <input name="C" type="hidden" value="5"> <input name="D" type="text" value="6"> <textarea name="E">7</textarea> <input name="F" type="checkbox" value="8" checked="checked"> <input name="F" type="checkbox" value="9"> <input name="F" type="checkbox" value="10" checked="checked"> <input name="G" type="radio" value="11"> <input name="G" type="radio" value="12" checked="checked"> <input name="G" type="radio" value="13"> <input name="H" type="password" value="14"> <input name="I" type="submit" value="15"> <input name="J" type="reset" value="16">对应的断言结论(摘自 test/test.js):
| 调用 | 期望结果 | 验证的规则 |
|---|---|---|
$('#fieldTest :checkbox').fieldValue(true) | ['8','10'] | 成功模式下未勾选的 value="9" 被排除 |
$('#fieldTest :checkbox').fieldValue(false) | ['8','9','10'] | false模式下所有 checkbox 的 value 都返回 |
$('#fieldTest :radio').fieldValue(false) | ['11','12','13'] | radio 组在非成功模式下整组返回 |
$('#fieldTest [name=B]').fieldValue(true) | ['3','4'] | select-multiple 只返回被选中项 |
$('#fieldTest :radio').fieldSerialize(true) | G=12 | radio 组只序列化被选中项 |
$('#fieldTest :radio').fieldSerialize(false) | G=11&G=12&G=13 | 非成功模式下整组序列化 |
$('#fieldTest input').fieldSerialize(true) | C=5&...&H=14 | submit(I) 与 reset(J) 在成功模式下不出现 |
$('#fieldTest :input').fieldSerialize(false) | 额外包含I=15&J=16 | false模式下 submit/reset 按钮的 value 也被序列化 |
这些用例把successful参数对 checkbox、radio、submit、reset 四类控件的差异影响验证得非常完整。阅读测试表单 test/test.html 与断言 test/test.js 是快速校准“我的用法会得到什么结果”的最可靠途径。
综合测试表单:一次覆盖所有控件类型
docs/form-fields.md 附带了一个交互演示页:输入任意 jQuery 选择器(如:text、:radio、textarea、[type='hidden']、:checkbox等),即可对下方测试表单运行fieldValue与fieldSerialize,并可勾选“仅成功控件”开关切换successful参数。该演示表单覆盖了各类控件,这里完整保留,方便本地搭建自己的验证页面:
<form id="test" action="dummy.php" method="post"> <strong>Test Form</strong> <table> <tr><td><input type="hidden" name="Hidden" value="secret"></td> <td><input type="hidden" name="Hidden" value="secret"></td></tr> <tr><td><input name="Name" type="text" value="MyName1"></td> <td><input name="Name" type="text" value="MyName1"></td></tr> <tr><td><input name="Password" type="password"></td> <td><input name="Password" type="password" value=""></td></tr> <tr><td><select name="Multiple" multiple="multiple"></td> <td><select name="Multiple" multiple="multiple"> <option value="one" selected="selected">One</option> <option value="two">Two</option> <option value="three">Three</option> </select></td></tr> <tr><td><select name="Single"></td> <td><select name="Single"> <option value="one" selected="selected">One</option> <option value="two">Two</option> <option value="three">Three</option> </select></td></tr> <tr><td colspan="2"><input type="checkbox" name="Check" value="1"> <input type="checkbox" name="Check" value="2"> <input type="checkbox" name="Check" value="3"> <input type="checkbox" name="Check2" value="4"> <input type="checkbox" name="Check2" value="5"> <input type="checkbox" name="Check3"></td></tr> <tr><td colspan="2"><input type="radio" name="Radio" value="1"> <input type="radio" name="Radio" value="2"> <input type="radio" name="Radio" value="3"> <input type="radio" name="Radio2" value="4"> <input type="radio" name="Radio2" value="5"></td></tr> <tr><td><textarea name="Text" rows="2" cols="20"></textarea></td> <td><textarea name="Text" rows="2" cols="20"></textarea></td></tr> <tr><td><input type="reset" name="resetButton" value="Reset"></td> <td><input type="reset" name="resetButton" value="Reset"></td></tr> <tr><td><input type="submit" name="sub" value="Submit"></td> <td><input type="submit" name="submitButton" value="Submit"></td></tr> </table> </form>注意其中name="Check"的三个 checkbox 与未带 value 的Check3:前者用于观察同名多值的展开,后者用于观察“无 value 属性时 checkbox 取什么值”这类边界行为。
实战要点与常见误区
局部提交的标准姿势。表单很大但服务端只关心部分字段时:
// 只提交 .specialFields 组内的字段 var queryString = $('#myFormId .specialFields').fieldSerialize(); $.post('myscript.php', queryString);选择器本身(
:text、:input、属性选择器、类名等)就是“字段子集”的定义,灵活性远高于formSerialize。fieldValue 是纯取值,fieldSerialize 才做编码。需要拿到原始值数组做前端校验/展示时用
fieldValue;需要把数据发出去时用fieldSerialize或$.param自行组装。不要假设未勾选的 checkbox 有值。默认(
successful为 true)时,未勾选的 checkbox 既不产生fieldValue结果,也不会出现在fieldSerialize字符串中——这与浏览器原生提交行为一致。若后端期望“未勾选时也传一个标记值”,应改用fieldValue(false)/fieldSerialize(false),或提交前显式补一个隐藏字段。radio 组在
false模式下的语义要当心:fieldSerialize(false)会把组内所有 radio(含未选中的)都序列化进去(测试断言G=11&G=12&G=13),这与原生表单语义差异很大,通常只用于调试或需要完整快照的场景。submit/image 按钮值只在“被点击”时有效。成功模式下只有
form.clk(本次点击的按钮)才取值;reset、button类型则恒无值。从源码结构看,这与formToArray里对form.clk_x/form.clk_y坐标的特殊处理共同构成了图片按钮提交的完整支持。textarea 换行会被规范化为
\r\n(rCRLF替换),跨平台拼接多行文本时可以放心使用fieldValue的结果。
小结
fieldValue与fieldSerialize是 jQuery Form Plugin 中字段级数据访问的基石:前者以“始终返回数组”的契约提供各控件类型的当前值,后者把字段子集编码为可直接传输的查询字符串。二者共用successful参数来对齐浏览器“成功控件”语义,并共享同一套底层取值逻辑($.fieldValue),这套逻辑同样服务于formToArray→ajaxForm/ajaxSubmit的提交流程。遇到取值或序列化结果“不符合预期”时,按“是否无 name / 是否 disabled / 勾选状态 / 按钮是否被点击 / select 是否有选中项”这条判定链逐一排查,并对照 test/test.js 的断言预期,基本都能快速定位原因。
- 前端
【免费下载链接】form
jQuery Form Plugin
相关推荐
jQuery Form终极指南:5个fieldValue方法技巧轻松获取表单字段值
jQuery Form终极指南:5个fieldValue方法技巧轻松获取表单字段值 jQuery Form插件是一个强大的JavaScript库,专门用于简化H
前端jQuery Form数据序列化终极指南:formSerialize与fieldSerialize使用技巧
jQuery Form数据序列化终极指南:formSerialize与fieldSerialize使用技巧 jQuery Form插件是前端开发中处理表单AJA
前端jQuery Form Plugin API 深度解析:ajaxForm、ajaxSubmit 与表单序列化方法全解
jQuery Form Plugin API 深度解析:ajaxForm、ajaxSubmit 与表单序列化方法全解 jQuery Form Plugin 的核
前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考