一个 input 的 22 种身份:type state 与值净化
<input> 是平台里最名实不符的一个元素:同一个标签,靠 type 属性切出 22 种 type state——从单行文本到日期选择器、颜色选择器、滑块、文件上传、单选复选,再到提交按钮,行为各异。规范用四件事把这 22 种身份区分开:value 属性如何被解读(四类
value 模式)、读取 value 时跑哪种 value sanitization algorithm、哪些 content attribute 对它生效、以及暴露哪些 IDL(valueAsNumber / valueAsDate / stepUp())。本页用一个 live <input> 当场切换
type,把净化与模式差异打出来。校验细节见 约束校验,提交时各 type 如何进 entry list 见 提交与编码。
1 · type 是 enumerated attribute:非法 / 缺失都回落 text
type 是一个 enumerated attribute:只有 22 个已知关键字有效;写了规范不认的值(如 type="datetimepicker")、或干脆不写 type,它的 missing value default 与 invalid value default 都是 Text。这意味着 el.type 这个 IDL 读出来永远是规范化后的合法关键字——写非法值进去,读出来就是 "text"。
试一下净化。选 number 后在框里输 12abc 再点「读 .value」——净化算法判定它不是 valid floating-point number,直接把 value 抹成空串。选 color 输 red,净化成 #ff0000(能解析的 CSS
颜色都会被换算成十六进制形态,解析不了的才落到 #000000)。选 email 加 multiple 输 " a@x.com , b@y.com ",按逗号分段、各段去首尾空白。净化在设值时完成,且只作用于 IDL value,content attribute 不受影响:实测
setAttribute('value', '12abc') 后 .value 为空串,而 getAttribute('value') 与 defaultValue 仍是 12abc。
2 · 四类 value 模式:value 属性到底意味着什么
规范(4.10.5.5 起)把 22 个 type 归进四种 value 模式,核心区别是 IDL .value 反映什么、value content attribute 起什么作用:
value 模式——.value 即当前用户值,value attr 仅作默认值(dirty 前):
| type | 含义与净化要点 |
|---|---|
text · search |
单行文本。净化:去掉所有换行符(CR / LF)。支持 pattern / maxlength / minlength / placeholder / list。 |
tel · password |
电话 / 密码。同样净化去换行;tel 不强制格式(国际号码差异大),格式化交给 inputmode 与脚本。 |
url · email |
URL / 邮箱。净化:去首尾空白;email 配 multiple 时按逗号分段、各段分别去空白。支持 list。 |
date · month · week · time · datetime-local |
日期时间。净化:必须是对应格式的合法串,否则抹成空串。支持 min / max / step;IDL 有 valueAsNumber,date/month/week/time 还有 valueAsDate。 |
number · range |
数值 / 滑块。number:非 valid floating-point 则抹空。range:clamp 到 [min,max] 并贴到 step,默认值取 min 与 max 的中点,只有 max < min 时才回落到 min(实测 min=10 max=20 得 "15",min=10 max=5
得 "10")。两者支持 min / max / step + valueAsNumber / stepUp() / stepDown()。
|
color |
颜色。规范已改为接受任意 CSS 颜色再净化:实测 Chrome 151 下 red 得 #ff0000、rgb(0 128 0) 得 #008000、#ABCDEF 得小写 #abcdef,只有真正解析不了的串才落到 #000000(核对于 2026-08)。新增的 alpha 与
colorspace 尚未在本机 Chrome 151 暴露;colorspace=display-p3 时值不再是 #rrggbb 形态。不支持 min/max/step。
|
default/on 模式——关键是 checkedness,value attr 默认 "on":
| type | 含义与净化要点 |
|---|---|
checkbox · radio |
复选 / 单选。提交时收集的是 checked 与否,而非框里的文本;.value 是被选中时上送的值(默认字符串 "on")。支持 checked;radio 同 name 互斥。
|
filename 模式——.value 只读出占位路径,脚本只能置空:
| type | 含义与净化要点 |
|---|---|
file |
文件上传。.value 读出 C:\fakepath\<名>(安全限制,藏真实路径);脚本只能把它设为 "",设成别的会抛 InvalidStateError(实测);真实文件在 .files(FileList)。支持 multiple / accept。
|
default 模式——value attr 只是按钮文案,无用户值:
| type | 含义与净化要点 |
|---|---|
submit · reset · button · image |
按钮。value 只决定按钮上的文字(image 是图形提交按钮:用 src / alt,提交坐标 name.x / name.y)。不接受文本输入。 |
hidden |
隐藏域,同属 default 模式。无净化、无 UI;.value 读的是 content attribute,写 .value 会连 value 属性一起改(实测),带 name 时照常提交。 |
3 · type 与净化在 IDL 上的对应
<!-- type 是 enumerated attribute:非法 / 缺失都回落 text -->
<input type="datetimepicker"> <!-- el.type === "text" -->
<input> <!-- el.type === "text"(缺失默认) -->
<!-- value sanitization:设进去脏值,读出来已净化 -->
const n = document.createElement('input');
n.type = 'number';
n.value = '12abc'; n.value; // ""(非 valid float,抹空)
n.value = '3.14'; n.valueAsNumber; // 3.14
n.stepUp(); n.value; // 受 step / min / max 约束
const c = document.createElement('input');
c.type = 'color'; c.value = 'red'; c.value; // "#ff0000"(可解析的 CSS 颜色 → 十六进制)
const e = document.createElement('input');
e.type = 'email'; e.multiple = true;
e.value = ' a@x.com , b@y.com '; // 各段去首尾空白
<!-- 四类 value 模式的 .value 含义不同 -->
checkbox.checked // default/on:收的是 checkedness,不是文本
file.value // filename:"C:\\fakepath\\photo.png"(藏真实路径)
file.files // FileList —— 真正拿文件的入口
submit.value // default:只是按钮上的文字
非法 type 静默回落 text,不报错。写 <input type="datetime">(老规范已废弃)或任何拼错的关键字,浏览器不会抛错,只是把它当作 type=text 渲染并解读 value。结果是日期校验、valueAsDate 全部失效却毫无提示——依赖
el.type 而非写下的 attribute 才靠得住。
type=number 与 inputmode=numeric 是两件事。type=number 带来净化、valueAsNumber、stepUp/stepDown 与 spinner。它不接受非数字字符(整串抹空),也不适合把值当定长字符串看待——stepUp()
之类的写回会把值重新格式化,不适合邮编 / 卡号 / 验证码这类「看着像数字、是定长字符串」的字段。这类字段更宜 type=text + inputmode=numeric + pattern:既调出数字软键盘,又不被净化抹空。取舍详见 inputmode。
type=file 的 C:\fakepath\ 是有意的安全限制。历史上脚本读 input.value 能拿到本地真实路径,泄露用户目录结构,于是规范规定 file 控件的 .value getter 恒返回 C:\fakepath\<文件名>,setter 只接受空串(用于清空)。要拿文件得走 input.files;要展示多文件得开 multiple。