应使用 document.createelement 创建 input 元素,设 type、name(必填,推荐数组式命名如 "emails[]")、placeholder 等属性,并确保其在 form 内、未 disabled,以保障 formdata 正确收集。

用 document.createElement 创建 input 而不是拼接字符串
直接修改 innerHTML 会重置已有输入框的值、丢失焦点、清空事件监听器,还可能触发意外重绘。必须用原生 DOM 方法创建和插入。
- 用
document.createElement('input')新建节点,再设type、name、placeholder等属性 -
name必须设——没name的<input>不会被FormData收集,后端收不到 - 推荐数组式命名:如
name="emails[]"或带索引的name="user[phone][0]",便于后端解析 - 如果需要唯一标识(比如绑定
<label for="xxx"></label>),给每个id加时间戳或递增序号,避免重复
删除动态行时要同步清理 DOM 和数据引用
只调用 element.remove() 是不够的。如果你在 JS 中维护了一个 inputList = [] 数组来跟踪所有动态项,删 DOM 却不删数组,后续遍历或提交就会出错。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 删除按钮应放在每行的父容器里(如
<div class="field-row">),点击时用 <code>event.target.closest('.field-row').remove() - 若业务逻辑依赖数组状态,删除前需用
inputList = inputList.filter(item => item.id !== targetId) - 别用
display: none伪装删除——它仍会随表单提交空值 - 只剩一个输入项时,可加逻辑禁用删除按钮,防止用户误操作后无法输入
- 提交前加一句:
console.log([...new FormData(form).entries()]),一眼看清哪些字段进了 FormData - 动态生成的
<input type="hidden">同样要设name,否则静默丢弃 - iOS 上某些场景下,新插入的 input 可能未获得焦点或被遮挡,导致用户看不见光标——添加后立即调用
inputEl.focus()并确保其在视口内 - Vue:用
ref获取容器后,仍应通过fields.push({})修改响应式数组驱动渲染 - React:用
useState管理表单项列表,每次添加调用setFields(prev => [...prev, { id: Date.now() }]) - 强行混用 DOM 操作和框架状态,会导致视图和数据不同步,调试时容易陷入“明明看到输入了,但提交就是没值”的死循环
提交前校验动态字段是否真被 FormData 收集
很多人调试时发现控制台打印有值,但后端收不到,问题往往出在 name 缺失、被设为 disabled,或元素不在 <form></form> 内部。
Vue/React 里别混用 DOM 操作和响应式状态
在框架中手动 appendChild() 新增的 <input>,不会受 v-model 或 useState 管理,提交时必然为空。
FormData ——靠猜不如跑一次 console.log。










