如何将封装的jQuery序列化函数转为可复用的原生JS命名函数
表单序列化函数改造方案:移除jQuery依赖并转为可复用命名函数
完全理解你的需求——把绑定在jQuery上的序列化逻辑改成独立可复用的原生JS函数,这样就能在多页面共享,甚至为后续模块化开发铺路。我已经把原jQuery插件改造成了无依赖的标准命名函数,同时保留了原有的所有功能,还做了一些易用性优化:
改造后的完整函数
function serializeObject(formNameOrElement) { // 兼容传入表单ID字符串或直接传入DOM元素 const form = typeof formNameOrElement === 'string' ? document.getElementById(formNameOrElement) : formNameOrElement; if (!form || form.tagName !== 'FORM') { throw new Error('请传入有效的表单元素或表单ID'); } let json = {}; const pushCounters = {}; const patterns = { validate: /^[a-zA-Z][a-zA-Z0-9_]*(?:\[(?:\d*|[a-zA-Z0-9_]+)\])*$/, key: /[a-zA-Z0-9_]+|(?=\[\])/, push: /^$/, fixed: /^\d+$/, named: /^[a-zA-Z0-9_]+$/ }; // 工具函数:构建嵌套结构 const build = (base, key, value) => { base[key] = value; return base; }; // 工具函数:处理数组push计数 const pushCounter = (key) => { if (pushCounters[key] === undefined) { pushCounters[key] = 0; } return pushCounters[key]++; }; // 原生方式获取表单数据,替代jQuery.serializeArray() const formData = new FormData(form); const serializedArray = Array.from(formData.entries()).map(([name, value]) => ({ name, value })); serializedArray.forEach(item => { // 跳过不符合规则的字段名 if (!patterns.validate.test(item.name)) { return; } let keys = item.name.match(patterns.key); let merge = item.value; let reverseKey = item.name; while (keys.length > 0) { const k = keys.pop(); // 移除当前层级的键名,用于反向构建 reverseKey = reverseKey.replace(new RegExp(`\\[${k}\\]$`), ''); if (k.match(patterns.push)) { merge = build([], pushCounter(reverseKey), merge); } else if (k.match(patterns.fixed)) { merge = build([], k, merge); } else if (k.match(patterns.named)) { merge = build({}, k, merge); } } // 实现深度合并,替代jQuery.extend(true, ...) const deepMerge = (target, source) => { for (const key in source) { if (source[key] instanceof Object && target[key] instanceof Object) { deepMerge(target[key], source[key]); } else { target[key] = source[key]; } } return target; }; json = deepMerge(json, merge); }); return json; }
核心改造点说明
- 彻底移除jQuery依赖:用原生
FormDataAPI获取表单数据,用DOM选择器替代jQuery的元素操作,完全不需要引入jQuery - 转为全局可复用函数:直接定义
serializeObject全局函数,你可以把它保存到单独的form-utils.js文件里,在需要的页面通过<script src="form-utils.js"></script>引入即可使用 - 增强参数灵活性:支持传入表单ID字符串(比如
serializeObject('userForm'))或者直接传入表单DOM元素,比原插件的调用方式更灵活 - 保留原有的序列化逻辑:所有处理嵌套字段(比如
array[]、obj[key])的规则完全和原插件一致,不会改变原有功能
调用示例
在任意页面引入函数后,你可以这样调用:
- 通过表单ID调用:
// 假设表单ID是"loginForm" const loginData = serializeObject('loginForm'); console.log(loginData);
- 通过DOM元素调用:
const formElement = document.querySelector('#signupForm'); const signupData = serializeObject(formElement); // 提交数据或其他处理...
面向React等模块化开发的扩展
如果之后要迁移到React或者其他模块化项目,只需要把这个函数改成ES模块格式:
// form-utils.js 改为ES模块 export function serializeObject(formNameOrElement) { // 函数内容和上面完全一致 }
然后在React组件里导入使用:
import { serializeObject } from './form-utils.js'; function SignupForm() { const handleSubmit = (e) => { e.preventDefault(); const formData = serializeObject(e.target); // 调用API提交数据... }; return ( <form onSubmit={handleSubmit}> {/* 表单控件 */} </form> ); }
内容的提问来源于stack exchange,提问作者cryophoenix
相关产品推荐
相关产品推荐

