☰
jQuery Form Plugin 的 fieldValue 与 fieldSerialize:字段级取值与部分序列化的深度实战指南
2026/10/13 9:56:06 网站建设 项目流程
  • 前端

【免费下载链接】form

jQuery Form Plugin

项目地址:https://gitcode.com/gh_mirrors/fo/form
点击查看免费下载

本篇基于 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/clearFieldsform / 字段集合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; };

要点有二:

  1. 无效值被静默过滤:单个元素返回null、undefined或空数组时直接continue,所以“始终返回数组”且数组里不会出现空槽。
  2. 多值控件展开合并:一个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&amp;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=12radio 组只序列化被选中项
$('#fieldTest :radio').fieldSerialize(false)G=11&G=12&G=13非成功模式下整组序列化
$('#fieldTest input').fieldSerialize(true)C=5&...&H=14submit(I) 与 reset(J) 在成功模式下不出现
$('#fieldTest :input').fieldSerialize(false)额外包含I=15&J=16false模式下 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>&lt;input type="hidden" name="Hidden" value="secret"&gt;</td> <td><input type="hidden" name="Hidden" value="secret"></td></tr> <tr><td>&lt;input name="Name" type="text" value="MyName1"&gt;</td> <td><input name="Name" type="text" value="MyName1"></td></tr> <tr><td>&lt;input name="Password" type="password"&gt;</td> <td><input name="Password" type="password" value=""></td></tr> <tr><td>&lt;select name="Multiple" multiple="multiple"&gt;</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>&lt;select name="Single"&gt;</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>&lt;textarea name="Text" rows="2" cols="20"&gt;&lt;/textarea&gt;</td> <td><textarea name="Text" rows="2" cols="20"></textarea></td></tr> <tr><td>&lt;input type="reset" name="resetButton" value="Reset"&gt;</td> <td><input type="reset" name="resetButton" value="Reset"></td></tr> <tr><td>&lt;input type="submit" name="sub" value="Submit"&gt;</td> <td><input type="submit" name="submitButton" value="Submit"></td></tr> </table> </form>

注意其中name="Check"的三个 checkbox 与未带 value 的Check3:前者用于观察同名多值的展开,后者用于观察“无 value 属性时 checkbox 取什么值”这类边界行为。

实战要点与常见误区

  1. 局部提交的标准姿势。表单很大但服务端只关心部分字段时:

    // 只提交 .specialFields 组内的字段 var queryString = $('#myFormId .specialFields').fieldSerialize(); $.post('myscript.php', queryString);

    选择器本身(:text、:input、属性选择器、类名等)就是“字段子集”的定义,灵活性远高于formSerialize。

  2. fieldValue 是纯取值,fieldSerialize 才做编码。需要拿到原始值数组做前端校验/展示时用fieldValue;需要把数据发出去时用fieldSerialize或$.param自行组装。

  3. 不要假设未勾选的 checkbox 有值。默认(successful为 true)时,未勾选的 checkbox 既不产生fieldValue结果,也不会出现在fieldSerialize字符串中——这与浏览器原生提交行为一致。若后端期望“未勾选时也传一个标记值”,应改用fieldValue(false)/fieldSerialize(false),或提交前显式补一个隐藏字段。

  4. radio 组在false模式下的语义要当心:fieldSerialize(false)会把组内所有 radio(含未选中的)都序列化进去(测试断言G=11&G=12&G=13),这与原生表单语义差异很大,通常只用于调试或需要完整快照的场景。

  5. submit/image 按钮值只在“被点击”时有效。成功模式下只有form.clk(本次点击的按钮)才取值;reset、button类型则恒无值。从源码结构看,这与formToArray里对form.clk_x/form.clk_y坐标的特殊处理共同构成了图片按钮提交的完整支持。

  6. 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

项目地址:https://gitcode.com/gh_mirrors/fo/form
点击查看免费下载
上一篇:GetQzonehistory 实操:免费完整导出 QQ 空间历史说说、评论与高清图
下一篇:MuJoCo 刚柔耦合仿真完整指南:flexcomp 柔体建模与弹性参数调优

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询