HTML 事件属性:
<button onclick="displayDate()">Try it</button>
使用 HTML DOM 分配事件:
<script>
document.getElementById("myBtn").onclick = function(){ displayDate() };
</script>
这两者有什么区别?使用(使用 HTML DOM 分配事件)有什么优势吗?
谢谢
最佳答案
有很大的不同。
通过 HTML 事件属性设置的事件处理程序是我们进行事件处理的第一种方式——在 DOM 出现之前。这种设置事件的方式被称为 DOM Level 0(就像在有标准之前的事实标准一样)。当这是这样做的方式时(大约在 1995 年),这很好,因为我们别无选择。但是,属性值转换为事件处理代码的方式是这样处理的:
HTML 元素声明了一个事件属性,该属性的值是事件发生时应执行的 JavaScript 代码:
<input type="button" onclick="alert('You clicked me!')" value="Click me">
注意
onclick
的值不是函数引用,只是要运行的松散代码。这实际上是由浏览器通过在全局范围内创建一个函数来实现的,该函数充当所提供代码的包装器。我们可以在这里看到:
// Output the value of the onclick property.
// Note the value supplied in the HTML
// is wrapped in a function that we didn't create
alert(document.querySelector("input").onclick);
<input type="button" onclick="alert('You clicked me!')" value="Click me">
由于在全局包装函数中自动包装属性值,非直观的事情经常发生如下:
function foo(){
// This function is invoked by clicking the HTML input element
// so, we may reasonably expect that "this" would reference that
// element. But, as you'll see, it doesn't.
alert("You clicked the " + this.nodeName + " element.");
}
<input type="button" onclick="foo()" value="Click me">
以上报道
undefined
因为实际上,this
在那种情况下是指全局window
没有 nodeName
的对象属性(property)。但是,如果您不知道 Global wrapper(为什么会这样),这将非常令人困惑,因为 this
DOM 事件处理程序使用的几乎总是引用导致事件触发的 DOM 元素。当 DOM Level 1 事件处理规范问世(1998 年)时,一种新的事件配置方式也出现了。我们现在有了代表 HTML 元素的对象,每个对象都有映射到元素属性的属性。出于这个原因,许多人(直到今天)仍然认为使用属性或对象属性在很大程度上是同一回事。但是,有一些重要的区别(I've written about 在我的另一个答案中:参见答案的后半部分),因为属性用于设置值,这可能会影响状态,但属性用于覆盖属性和设置状态。
因此,使用 DOM 事件处理,我们将执行以下操作,您将看到,设置事件回调,不是作为要执行的松散代码,而是通过存储对要在事件发生时调用的函数的引用。因为我们提供了函数,所以它具有我们存储它的 DOM 对象的范围,我们不再需要用 Global 包装松散的命令。这会导致
this
绑定(bind)按预期工作:// Just a reference to a function is used with event
// properties. Not "loose" code. And, because the function
// is actually being stored with the DOM element, this binding
// works as expected.
document.querySelector("input").onclick = foo;
function foo(){
// This function is invoked by clicking the HTML input element
// so, we may reasonably expect that "this" would reference that
// element. But, as you'll see, it doesn't.
alert("You clicked the " + this.nodeName + " element.");
}
<input type="button" value="Click me">
DOM 事件处理的另一个好处是我们将 JavaScript 内容与 HTML 内容分开(即关注点分离)。这是一个好处,但不是改变的动力。
现在,在解释了这两种事件注册机制之间的区别之后,故事还没有完成。 DOM 事件属性仍然存在一个问题,如果你想设置多个事件处理程序,你没有一个干净的方法来做到这一点,因为你只能在给定的属性中存储一个函数引用。因此,对于现代事件处理,我们使用
.addEventListener()
,这允许我们为我们想要的事件注册尽可能多的事件回调,并且我们获得了额外的好处,即知道我们注册的回调将按照我们注册它们的顺序被调用。// Register an event listener:
document.querySelector("input").addEventListener("click", foo1);
// Register more event listeners:
document.querySelector("input").addEventListener("click", foo3);
document.querySelector("input").addEventListener("click", foo2);
function foo1(){ console.log("Hello from foo1"); }
function foo2(){ console.log("Hello from foo2"); }
function foo3(){ console.log("Hello from foo3"); }
<input type="button" value="Click me">
关于javascript - HTML 事件属性和使用 HTML DOM 分配事件有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27905060/