应使用 readonly 属性而非 setattribute('readonly') 切换只读状态,因后者在旧版 safari 中行为不一致;react 中必须用 readonly={boolean} 驼峰写法;切换时需配合 blur() 处理焦点并确保 :read-only 样式生效。

用 readOnly 属性而非 setAttribute('readonly') 切换状态
直接操作 DOM 元素的 readOnly(注意驼峰、首字母小写)属性是唯一跨浏览器稳定的方式。旧版 Safari 对 setAttribute / removeAttribute 处理不一致,尤其在表单重渲染或焦点残留时容易失效。
常见错误写法:
-
input.setAttribute('readonly', 'false')—— 依然只读,因为只要属性存在就生效 -
input.readOnly = false在 Safari 15 及更早版本中可能无反应
推荐写法:
- 设为只读:
input.readOnly = true - 解除只读:
input.readOnly = false - 检查状态:
if (input.readOnly),别用hasAttribute('readonly')
React 中必须用 readOnly 驼峰写法绑定
React 的 JSX 属性名遵循 DOM IDL 规范,readonly 是 HTML 内容属性,但 React 绑定的是 DOM 属性,所以必须写成 readOnly,且值必须是布尔类型。
错误示例:
-
<input readonly>—— JSX 不识别小写readonly,会被忽略 -
<input readonly>—— 字符串 "true" 不等于布尔true,React 不会触发更新
正确写法:
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
-
<input readonly>(isLocked是true或false) - 配合 useEffect 控制焦点:切换为只读后调用
inputRef.current?.blur(),避免键盘操作卡在已锁定字段
:read-only 伪类样式必须搭配真实 readonly 属性才生效
:read-only 是 CSS 选择器,它只匹配**当前具有 readonly 属性的元素**,不是靠 JS 设置 readOnly = true 就自动触发的。也就是说,DOM 层面必须存在该 HTML 属性,伪类才会命中。
这意味着:
- 用
input.readOnly = true切换状态时,:read-only样式通常能同步生效(现代浏览器基本支持),但旧版 Edge 或某些 WebView 里可能延迟或不触发 - 最稳妥的做法是:同时设置属性和 property:
input.setAttribute('readonly', 'readonly'); input.readOnly = true; - 若需兼容 IE 或老旧安卓 WebView,建议额外加 class:
input.classList.add('readonly');,再写input.readonly, input.readonly-class { … }
动态控制时别漏掉焦点与键盘陷阱
从可编辑切到只读,用户可能正聚焦在该 input 上。此时它仍保持焦点,但按方向键、Backspace 等无效,体验像“卡住”。更麻烦的是 Tab 导航:只读元素仍参与 tab 流,但 disabled 才跳过 —— 这个差异常被忽略。
实操建议:
- 切为只读前主动
input.blur(),防止焦点残留 - 切为 disabled 前,用
input.nextElementSibling?.focus()引导焦点,避免键盘用户迷失 - 如果字段本该可复制(如订单号),别用
disabled替代readonly,否则用户 Ctrl+C 失败,还导致后端收不到值
真正难的不是加属性,而是让状态切换后,焦点、可访问性、表单序列化、样式反馈全部对齐。一个 readOnly = true 调用只是起点,不是终点。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










