为什么<body>
元素的focus
和blur
事件只通过.on<...>
属性方法触发,而不是通过添加addEventListener
的回调触发?
以下简单示例可以在控制台中复制并运行:
const method = name => () => console.log(name);
document.body.addEventListener('blur', method('listener blur'));
document.body.addEventListener('focus', method('listener focus'));
document.body.onfocus = method('onfocus');
document.body.onblur = method('onblur');
切换到不同的选项卡会导致身体模糊,并切换回焦点
但只有onfocus
和onblur
为我登录,而没有listener focus
或listener blur
。
现代Chrome和Firefox都是如此;所以我想是有原因的吧?
TL;博士:
使用window.addEventListener
或document.addEventListener
,但决不能使用document.body.addEventListener
。
问题
问题是,<body>
没有focus
或blur
事件;CCD_ 16是这样。然而,可能是为了与非常旧的站点兼容,<body>
元素允许在文档上出现焦点/模糊时触发onfocus
和onblur
。
因此,在大多数情况下,使用window.addEventListener
应该有效,因为事件气泡从document
到window
。由于所有其他事件也会从体内冒出,因此最好也对其他事件使用window.addEventListener
(*除非有特定原因不这样做,例如传播停止时(。
这个问题显然也是滚动事件的情况,因为<html>
标记可能是滚动的实际内容。同样,使用window.addEventListener
会在它冒泡时捕获它。