应优先使用 css :focus 伪类替代 onfocus/onblur 内联脚本,因其自动响应所有聚焦方式、无需 js、样式与逻辑解耦;仅当需联动行为(如校验、滚动、下拉)时才用 addeventlistener 绑定 focus/blur 事件。

onfocus/onblur 直接触发样式变更的局限性
直接用 onfocus 和 onblur 属性写内联 JS 控制高亮(比如改 style.borderColor)看似简单,但很快会遇到问题:onfocus="this.style.borderColor='blue'" 这类写法无法复用、难调试,且一旦页面有多个输入框,就不得不复制粘贴多遍,稍一改样式就得全局搜替换。更关键的是:它和 CSS 本身的能力重复了——焦点状态本就有原生伪类 :focus 支持。
用 :focus 伪类替代 onfocus/onblur 更可靠
CSS 的 :focus 伪类自动响应所有合法获取焦点的方式(鼠标点击、Tab 切换、element.focus() 调用),无需 JS 干预,也不依赖元素是否可编辑。只要输入框是可聚焦的(input、textarea、select 默认就是),下面这行就够了:
input:focus { border-color: #007aff; outline: none; }
注意几点:
-
outline: none建议配合使用,否则部分浏览器(如 Chrome)会在:focus时叠加默认外边框,造成双线 -
:focus不支持 IE8 及更早版本,但当前已无实际兼容必要 - 如果需要失焦后恢复特定样式(比如浅灰边框),直接在基础选择器里定义:
input { border-color: #ccc; }
必须用 JS 监听 focus/blur 的真实场景
当高亮不只是改边框颜色,还涉及其他联动行为时,才真正需要 JS 绑定 focus 和 blur 事件(注意:addEventListener 用 "focus" 和 "blur",不是 "onfocus"):
- 点击输入框时显示下拉建议列表(如搜索框联想)
- 失焦时触发表单字段校验,并动态添加
errorclass - 聚焦时滚动到该输入框可视区域(
element.scrollIntoView({ block: 'nearest' })) - 需要区分“首次聚焦”和“反复进出”,得靠外部状态变量(如
let isFirstFocus = true)
示例(只改 class,让样式与逻辑解耦):
const input = document.querySelector('input');input.addEventListener('focus', () => {input.classList.add('focused');});input.addEventListener('blur', () => {input.classList.remove('focused');});
对应 CSS:
input.focused { border-color: #007aff; box-shadow: 0 0 4px rgba(0, 122, 255, 0.3); }
blur 时机比预期更“积极”,别依赖 click 判断
很多人以为 blur 只在用户点页面空白处才触发,其实不然。以下都会触发 blur:
- 按 Tab 键跳到下一个可聚焦元素(包括
button、a[href]) - 点击另一个
input或textarea - 切换浏览器标签页(部分浏览器)
- 调用
input.blur()或document.activeElement?.blur()
所以不要在 blur 回调里写 if (event.relatedTarget === null) {...} 来判断“是否点到了空白处”——relatedTarget 在 Tab 切换或标签页切换时为 null,但这时你并不想执行“清空提示文案”这类操作。真要区分,得结合 focusin/focusout 事件委托或记录上一个 active 元素。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











