onblur与addEventListener差异:为何body的blur事件仅前者生效?
为什么body绑定addEventListener("blur")无效,onblur却生效?
核心原因
blur事件本身是不冒泡的事件,浏览器对body.onblur有特殊代理处理:当整个页面(window)失去焦点时,浏览器会把这个事件同步触发到body的onblur属性上。但用addEventListener给body绑定blur时,由于body默认不是可聚焦元素,且blur不冒泡,window上的blur事件不会传递到body,所以绑定的回调不会执行。如果要监听页面失去焦点,应该直接给window绑定blur事件,而非body。
onblur与addEventListener的差异
- 绑定数量限制:
onblur是DOM元素的属性,同一时间只能绑定一个回调函数,新赋值的函数会直接覆盖旧的;addEventListener可以给同一个事件绑定多个不同的回调,触发时按绑定顺序依次执行。 - 事件阶段控制:
addEventListener支持第三个参数(useCapture),可选择在事件的捕获阶段或冒泡阶段触发回调;onblur只能在冒泡阶段触发(对blur这类不冒泡事件而言,这个特性几乎无用)。 - 移除方式不同:移除
onblur只需给元素的onblur属性赋值null;移除addEventListener绑定的回调,必须传入和绑定完全相同的函数引用,匿名函数无法被移除。 - 特殊代理行为:部分元素(如body)的
onxxx属性会被浏览器做特殊事件代理,比如body的onblur会代理window的blur事件,但addEventListener不会享受这个代理逻辑。
内容的提问来源于stack exchange,提问作者Caio
相关产品推荐
相关产品推荐

