一个 <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,净化成 #000000。选 email 加 multiple 输
" a@x.com , b@y.com ",按逗号分段、各段去首尾空白。这些净化发生在设置 value 之后、读取之前,所以脏数据存不进 DOM。
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(min < max 时为区间中点)。两者支持 min / max / step +
valueAsNumber / stepUp() / stepDown()。
|
color |
颜色。净化为合法的小写 #rrggbb,非法则 #000000。不支持 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\<名>(安全限制,藏真实路径);脚本只能把它设为 "",真实文件在 .files(FileList)。支持 multiple / accept。 |
default 模式——value attr 只是按钮文案,无用户值:
| type | 含义与净化要点 |
|---|---|
submit · reset · button · image |
按钮。value 只决定按钮上的文字(image 是图形提交按钮:用 src / alt,提交坐标 name.x / name.y)。不接受文本输入。 |
无 value(特例):
| type | 含义与净化要点 |
|---|---|
hidden |
隐藏域。无净化、无 UI;.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; // "#000000"(非法 → 黑)
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,但会拒绝前导零、不接受非数字字符,不适合邮编 / 卡号 / 验证码这类「看着像数字、其实是定长字符串」的字段。这类字段更宜
type=text + inputmode=numeric + pattern:既调出数字软键盘,又不丢前导零、不被净化抹空。取舍详见 inputmode。
type=file 的 C:\fakepath\ 是有意的安全限制。历史上脚本读 input.value 能拿到本地真实路径,泄露用户目录结构,于是规范规定 file 控件的 .value getter 恒返回 C:\fakepath\<文件名>,setter 只接受空串(用于清空)。要拿文件得走 input.files;要展示多文件得开 multiple。