起源是stackoverflow上的一个提问:在body上设置事件处理器(event handler),结果其却被添加到了全局window对象上。
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
body {
height: 1000px;
}
</style>
<title>Scroll</title>
</head>
<body>
<button id="btn">click</button>
<script type="text/javascript">
document.body.onscroll = function() {
alert(this);// displays [object Window], instead of [object HTMLBodyElement]
};
document.getElementById('btn').onclick = function() {
alert(this);// displays [object HTMLButtonElement]
}
</script>
</body>
</html>
答案在WHATWG的标注规范上可以找到:
Most of the time, the object that exposes an event handler is the same as the object on which the corresponding event listener is added. However, the
body
andframeset
elements expose several event handlers that act upon the element'sWindow
object, if one exists.来源:片段链接
大部分时候,允许添加事件处理器的对象,与之后被添加相应事件监听器的对象是一致的。然而body和framset元素有几个事件处理器,其对应的事件监听器却是被添加到Window对象上的(如果存在window对象)。
Event handler Event handler event type onblur
blur
onerror
error
onfocus
focus
onload
load
onresize
resize
onscroll
scroll
We call the set of the names of the event handlers listed in the first column of this table the
Window
-reflecting body element event handler set.来源:片段链接
我们将上表首栏一系列事件处理器称为“window反馈body元素事件处理器”(译者注:直译很拗口。意思就是,在body上设置了事件处理器,但该处理器却会被添加到window对象上,而不是HTMLBodyElement对象上。)
因此在上述事件处理器内使用this关键词,其指代window对象。