表单序列化
随着 Ajax 的出现,表单序列化成为一种常见需求
以将表单信息序列化为查询字符串为例
我们可以利用表单的 type 属性,以及 name 和 value 实现对表单的序列化
序列化应满足以下几点要求:
- 对表单字段和值进行 url 编码,使用 & 符号分割
- 不发送表单的禁用字段
- 只发送勾选的复选框和单选按钮
- 不发送 type 为 "reset" 和 "button" 的按钮
- 多项选择为每一个选中的项单独一个条目
- 在点击提交按钮提交的情况下,也会发送提交按钮(包括 image 的 input)
- <select> 的value值为 <option> 的value值,若<option>没有设置 value 那么值为 <option> 的文本值
序列化函数如下:
function serialize(form){ let parts = [], field = null; for(let i = 0, let len = form.elements.length; i < len; i++){ field = form.elements[i]; switch(field.type){ case "select-one": case "select-multiple":// 处理 select if(field.name.length){ for(let j = 0,let optLen = field.options.length,let option,let optValue; j < optLen; j++){ option = field.options[j]; if(option.selected){ optValue = ""; if(option.hasAttribute){// DOM optValue = (option.hasAttribute("value")?option.value:option.text); }else{// IE optValue = (option.attributes["value"].specified?option.value:option.text); } parts.push(encodeURIComponent(field.name)+"="+encodeURIComponent(optValue)); } } } break; case undefined:// 字段集 case "file":// 文件输入 case "submit":// 提交按钮 case "reset":// 重置按钮 case "button'": break; case "radio": // 单选按钮 case "checkbox": // 复选框 if(!field.checked){ break; } default:// 不包含没有 name 属性的表单字段 if(field.name.length){ parts.push(encodeURIComponent(field.name)+"="+encodeURIComponent(field.value)); } } } return parts.join("&");
}
通过上述函数就可以将一个表单序列化成一个查询字符串
如果需要序列化成其他特殊格式,过程与之大同小异
需要注意的地方在于:
如果表单中包含<fieldset>元素,那么该元素会出现在元素集合中,但是该元素没有 type 属性,所以上方的函数对 type 未定义的字段没有序列化