繁体   English   中英

HTML 事件属性和使用 HTML DOM 分配事件有什么区别?

[英]What is the difference between HTML Event Attributes and Assign Events Using the HTML DOM?

HTML 事件属性:

<button onclick="displayDate()">Try it</button>

使用 HTML DOM 分配事件:

<script>

document.getElementById("myBtn").onclick = function(){ displayDate() };

</script>

这两者有什么区别? 使用 (Assign Events Using the HTML DOM) 有什么好处?

谢谢

有很大的不同。

在有 DOM 之前,通过 HTML 事件属性设置的事件处理程序是我们进行事件处理的第一种方式。 这种设置事件的方式被称为 DOM Level 0(就像在没有标准之前的事实标准)。 当这是这样做的方式时(大约 1995 年),这很好,因为我们别无选择。 但是,属性值变成事件处理代码的方式是这样处理的:

HTML 元素声明了一个 event 属性,该属性的值是事件发生时应执行的 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属性。 但是,如果您不知道 Global 包装器(以及您为什么知道),这将非常令人困惑,因为 DOM 事件处理程序使用的this几乎总是引用导致事件触发的 DOM 元素。

当 DOM 级别 1 事件处理规范发布(1998 年)时,也出现了一种配置事件的新方法。 我们现在有代表 HTML 元素的对象,每个对象都有映射到元素属性的属性。 出于这个原因,许多人(直到今天)仍然相信使用属性或对象属性在很大程度上是一回事。 但是,有一些重要的区别( 我在我的另一个答案中已经写过:请参阅答案的后半部分),因为属性用于设置值,这会影响状态,但属性用于覆盖属性和设置状态。

因此,对于 DOM 事件处理,我们将执行以下操作,您将看到,设置事件回调,不是作为要执行的松散代码,而是通过存储对要在事件发生时调用的函数的引用。 因为我们提供了该函数,所以它具有我们存储它的 DOM 对象的范围,我们不再需要用 Global 来包装松散的命令。 这会导致this绑定按预期工作:

 // 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">

HTML5 规范的第6.1.5 节事件中描述了差异(或者更确切地说,连接)。 基本的区别是像onclick这样的事件属性包含这样执行的 JavaScript 代码(通常是函数调用),而元素节点的click属性是对函数定义的引用。 例如,如果您在 HTML 源代码中使用onclick="displayDate()" ,然后在浏览器的开发人员工具中检查 DOM,您会发现连接原则上更加复杂。

实际差异很大,取决于意见和编码风格。 使用onclick属性可以让任何阅读 HTML 源代码的人立即明白事件处理程序的存在。 当主要作为结构化数据读取 HTML 代码时,这也可能是不利的。 但是当几个元素需要具有相同的事件处理程序时,有一个明确的技术优势,例如,当您想要点击任何链接触发某个处理程序时(之前或代替正常的后续链接操作)。 使用 JavaScript,您可以创建一个循环,为所有链接分配相同的功能,这与在 HTML 标记中复制相同的onclick属性相反。

优点是您不会将 js 代码与 html 混淆,它允许您分离编程层。 这使您的代码更干净,更不容易出现错误。 符合 Web 可访问性规则和良好编程基础的实践。

没有区别。 OnClick 这是同一个事件。

如果您想调用不同的方法,使用 javascript 您可以操纵 OnClick 引发时要执行的操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM