原生 input 和 textarea 无法直接实现标签输入,因其不支持多值管理、独立标签渲染与删除交互;需用 JavaScript 手动监听键盘事件、动态创建标签节点并同步 hidden input 值。
<input type="text"> 本身不支持标签(Tag)输入,必须靠 JavaScript 手动实现或引入第三方库。浏览器原生没有 type="tag" 或类似语义化标签输入控件。
input 或 textarea 实现标签输入标签输入的核心行为是:用户输入文字 → 按空格/回车/逗号分隔 → 转为独立、可删除的标签块。而原生 <input type="text"> 只能维护单个字符串值;<textarea> 虽支持换行,但无法直观呈现已输入的标签、也不提供删除单个标签的 UI 入口。
name 属性无法直接映射多值<span class="tag">React</span>),原生 input 无法内嵌 HTML不依赖框架,用一个隐藏的 <input type="hidden"> 存最终值,配合 <div contenteditable="false"> 模拟输入区 + 标签容器:
<div class="tag-input"> <div class="tag-list" aria-live="polite"></div> <input type="text" class="tag-input-field" placeholder="输入标签,按 Enter 添加"> <input type="hidden" name="tags" value=""></div>
关键逻辑要点:
立即学习“前端免费学习笔记(深入)”;
input 的 keydown:捕获 Enter、,、Space,提取当前输入内容,清空输入框,插入新标签节点data-value 属性,并绑定点击删除事件(移除自身 + 更新 hidden input 的 value)value 推荐用 JSON 字符串(如 ["html","css"])或逗号分隔(如 html,css),避免解析歧义blur 事件:若输入框非空,应自动转为标签,否则用户可能误以为输入丢失autocomplete 和 list 属性对标签输入没用<input list> 配合 <datalist> 只能提供下拉建议,不能限制或结构化输入内容。它不会阻止用户输入任意文本,也无法将选中项自动转为标签。如果你希望支持「从预设列表中选择标签」+「允许自由输入」,得自己实现下拉面板(用 <ul> + position: absolute),并手动同步选中状态与标签列表。
autocomplete="off" 对标签输入无意义——浏览器不会记住“多个标签”的组合list 属性只影响单次输入建议,不参与标签创建流程aria-label(如 aria-label="添加技术标签")和 role="textbox",用于辅助技术识别手写标签输入看似简单,但边界情况极多:中文输入法组合字符、粘贴多标签文本(含换行/制表符)、移动端软键盘行为、屏幕阅读器焦点流、键盘导航(Tab/Shift+Tab)、国际化分隔符(如日语用顿号、法语用分号)……这些都会快速拖垮开发节奏。
<el-tag> + <el-input> 组合、Ant Design 的 <Select mode="tags">
name 必须与后端约定一致;若后端期望数组,前端提交时别忘了用 JSON.stringify() 或服务端解析逗号分隔字符串标签输入真正的难点不在“怎么加”,而在“怎么删得自然”“怎么粘贴不崩”“怎么让读屏软件知道当前有几个标签”。别在基础交互上重复造轮子,尤其当项目要上线时。