Javascript 事件:window.event 与参数引用(函数)
Javascript events: window.event vs argument reference (function)
有什么区别:
function test (e) {
console.log("Event: ", e);
}
document.querySelector("button").onclick = test;
<button>Click!</button>
和:
function test () {
console.log("Event: ", event); // same as window.event
}
document.querySelector("button").onclick = test;
<button>Click!</button>
它们似乎 return 完全相同的对象,甚至包含相同的 timeStamp
毫秒值。
我经常看到代码使用第一个例子,使用e
或evt
,但是第二个例子有什么问题?
我明白event
和window.event
是一样的,都是全局变量,但是如果event
也一样,用e
的目的是什么事情?
标准方式
有两种添加事件侦听器的标准方法:事件处理程序和 addEventListener
。
事件处理程序
最初是 DOM0(未由任何规范定义但被广泛实施),它们在 HTML5 spec.
中正确定义
Many objects can have event handlers specified. These act as
non-capture event listeners for the object on which they are
specified. [DOM]
An event handler has a name, which always starts with "on
" and
is followed by the name of the event for which it is intended.
An event handler can either have the value null, or be set to a
callback object, or be set to an internal raw uncompiled handler.
The EventHandler
callback function type describes how this is
exposed to scripts. Initially, event handlers must be set to null.
Event handlers are exposed in one of two ways.
The first way, common to all event handlers, is as an event handler
IDL attribute.
The second way is as an event handler content attribute.
事件处理程序 IDL 属性
An event handler IDL attribute is an IDL attribute for a specific
event handler. The name of the IDL attribute is the same as the
name of the event handler.
事件处理程序将是分配给 IDL 属性的函数。该函数(或回调)将以事件作为其唯一参数被调用:
Invoke callback with one argument, the value of which is the
Event
object E
示例:
document.querySelector("button").onclick = function(evt) {
console.log('Event: ' + evt);
};
<button>Click!</button>
事件处理程序内容属性
An event handler content attribute is a content attribute for a
specific event handler. The name of the content attribute is the
same as the name of the event handler.
当你设置它们时,处理程序将是一个 internal raw uncompiled handler. That means that getting the current value of the event handler 会更复杂:字符串将被解析为一个函数的 FunctionBody
,该函数有一个名为 event
的参数:
Let the function have a single argument called event
.
示例:
<button onclick="console.log('Event: ' + event);">Click!</button>
document.querySelector("button").setAttribute('onclick',
"console.log('Event: ' + event);"
);
<button>Click!</button>
添加事件监听器
它是由DOM L2 Events, and now DOM4引入的,定义为:
The addEventListener(type, callback, capture)
method must run these
steps:
If callback is null, terminate these steps.
Append an event listener to the associated list of event listeners with type set to type, callback set to
callback, and capture set to capture, unless there already is an event listener in that list with the same type,
callback, and capture.
当事件侦听器为 invoked 时,将以事件作为唯一参数调用回调:
Call listener's callback's handleEvent
, with the event passed
to this algorithm as the first argument
示例:
document.querySelector("button").addEventListener('click', function(evt) {
console.log('Event: ' + evt);
});
<button>Click!</button>
兼容性说明
旧版 IE 不支持 addEventListener
,并且不向事件处理程序传递任何参数。
但是,它提供了另一种访问事件的方法:window
对象从 Window.prototype
继承了 event
属性。 属性 有一个 getter 其中 returns 事件对象。
因此,支持旧 IE 的常用方法是使用参数并在必要时用 window.event
覆盖它:
document.querySelector("button").onclick = function(evt) {
evt = evt || window.event;
console.log('Event: ' + evt);
};
<button>Click!</button>
新 IE 将事件作为参数传递给 addEventListener
和事件处理程序,因此不再需要这样做。它还继续实施 Window.prototype.event
.
类似地,Chrome 实现了 window.event
,可能是为了支持为 IE 编写的旧代码。
但是,最好避免使用:
- 不标准。
- 标准替代品得到广泛实施(旧 IE 除外)。
- 它不适用于所有浏览器,例如 Firefox。
有什么区别:
function test (e) {
console.log("Event: ", e);
}
document.querySelector("button").onclick = test;
<button>Click!</button>
和:
function test () {
console.log("Event: ", event); // same as window.event
}
document.querySelector("button").onclick = test;
<button>Click!</button>
它们似乎 return 完全相同的对象,甚至包含相同的 timeStamp
毫秒值。
我经常看到代码使用第一个例子,使用e
或evt
,但是第二个例子有什么问题?
我明白event
和window.event
是一样的,都是全局变量,但是如果event
也一样,用e
的目的是什么事情?
标准方式
有两种添加事件侦听器的标准方法:事件处理程序和 addEventListener
。
事件处理程序
最初是 DOM0(未由任何规范定义但被广泛实施),它们在 HTML5 spec.
中正确定义Many objects can have event handlers specified. These act as non-capture event listeners for the object on which they are specified. [DOM]
An event handler has a name, which always starts with "
on
" and is followed by the name of the event for which it is intended.An event handler can either have the value null, or be set to a callback object, or be set to an internal raw uncompiled handler. The
EventHandler
callback function type describes how this is exposed to scripts. Initially, event handlers must be set to null.Event handlers are exposed in one of two ways.
The first way, common to all event handlers, is as an event handler IDL attribute.
The second way is as an event handler content attribute.
事件处理程序 IDL 属性
An event handler IDL attribute is an IDL attribute for a specific event handler. The name of the IDL attribute is the same as the name of the event handler.
事件处理程序将是分配给 IDL 属性的函数。该函数(或回调)将以事件作为其唯一参数被调用:
Invoke callback with one argument, the value of which is the
Event
object E
示例:
document.querySelector("button").onclick = function(evt) {
console.log('Event: ' + evt);
};
<button>Click!</button>
事件处理程序内容属性
An event handler content attribute is a content attribute for a specific event handler. The name of the content attribute is the same as the name of the event handler.
当你设置它们时,处理程序将是一个 internal raw uncompiled handler. That means that getting the current value of the event handler 会更复杂:字符串将被解析为一个函数的 FunctionBody
,该函数有一个名为 event
的参数:
Let the function have a single argument called
event
.
示例:
<button onclick="console.log('Event: ' + event);">Click!</button>
document.querySelector("button").setAttribute('onclick',
"console.log('Event: ' + event);"
);
<button>Click!</button>
添加事件监听器
它是由DOM L2 Events, and now DOM4引入的,定义为:
The
addEventListener(type, callback, capture)
method must run these steps:
If callback is null, terminate these steps.
Append an event listener to the associated list of event listeners with type set to type, callback set to callback, and capture set to capture, unless there already is an event listener in that list with the same type, callback, and capture.
当事件侦听器为 invoked 时,将以事件作为唯一参数调用回调:
Call listener's callback's
handleEvent
, with the event passed to this algorithm as the first argument
示例:
document.querySelector("button").addEventListener('click', function(evt) {
console.log('Event: ' + evt);
});
<button>Click!</button>
兼容性说明
旧版 IE 不支持 addEventListener
,并且不向事件处理程序传递任何参数。
但是,它提供了另一种访问事件的方法:window
对象从 Window.prototype
继承了 event
属性。 属性 有一个 getter 其中 returns 事件对象。
因此,支持旧 IE 的常用方法是使用参数并在必要时用 window.event
覆盖它:
document.querySelector("button").onclick = function(evt) {
evt = evt || window.event;
console.log('Event: ' + evt);
};
<button>Click!</button>
新 IE 将事件作为参数传递给 addEventListener
和事件处理程序,因此不再需要这样做。它还继续实施 Window.prototype.event
.
类似地,Chrome 实现了 window.event
,可能是为了支持为 IE 编写的旧代码。
但是,最好避免使用:
- 不标准。
- 标准替代品得到广泛实施(旧 IE 除外)。
- 它不适用于所有浏览器,例如 Firefox。