【问题标题】:What is the difference between HTML Event Attributes and Assign Events Using the HTML DOM?HTML 事件属性和使用 HTML DOM 分配事件有什么区别?
【发布时间】:2015-03-10 09:36:54
【问题描述】:

HTML 事件属性:

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

使用 HTML DOM 分配事件:

<script>

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

</script>

这两者有什么区别?使用(使用 HTML DOM 分配事件)有什么好处?

谢谢

【问题讨论】:

  • 我想重点是:把事情分开。不要将 javascript 或 CSS 放在 HTML 标记的中间。如果您要寻找一个原因,那就这样吧。其余的,两者都工作得很好。

标签: javascript html dom dhtml


【解决方案1】:

有很大的不同。

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

HTML 元素上声明了一个事件属性,该属性的值是事件发生时应执行的 JavaScript 代码:

&lt;input type="button" onclick="alert('You clicked me!')" value="Click me"&gt;

注意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);
&lt;input type="button" onclick="alert('You clicked me!')" value="Click me"&gt;

由于在全局包装函数中自动包装属性值,非直观的事情经常发生如下:

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.");
}
&lt;input type="button" onclick="foo()" value="Click me"&gt;

上面报告了undefined,因为实际上,this 在该上下文中指的是全局window 对象,它没有nodeName 属性。但是,如果您不知道 Global wrapper(为什么会这样),这将非常令人困惑,因为 DOM 事件处理程序使用的 this 几乎总是引用导致事件触发的 DOM 元素。

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

因此,使用 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.");
}
&lt;input type="button" value="Click me"&gt;

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"); }
&lt;input type="button" value="Click me"&gt;

【讨论】:

  • 我很抱歉用这样的垃圾邮件偷袭你,但你似乎对事件处理程序了解很多,你能不能看看你能不能知道发生了什么here
【解决方案2】:

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

实际的区别在于意见和编码风格。使用onclick 属性可以让任何阅读HTML 源代码的人立即清楚地知道存在事件处理程序。当主要将 HTML 代码作为结构化数据读取时,这也可能是不利的。但是当多个元素需要具有相同的事件处理程序时,有一个明确的技术优势,例如当您想要单击 any 链接时会触发一些处理程序(在正常的后续链接操作之前或代替正常的后续链接操作)。使用 JavaScript,您可以有一个循环,将相同的函数分配给所有链接,这与在 HTML 标记中复制相同的 onclick 属性相反。

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 没有。事件回调的建立方式和潜在的副作用存在很大差异。请参阅下面的详细答案。
    【解决方案4】:

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

    如果你想调用不同的方法,你可以使用 javascript 来控制 OnClick 引发时的操作。

    【讨论】:

    • 虽然事件相同,但这两种技术在配置回调的方式上却大不相同。两者的适用范围不同。
    猜你喜欢
    • 1970-01-01
    • 2011-09-18
    • 2012-11-02
    • 2012-09-17
    • 1970-01-01
    • 1970-01-01
    • 2016-04-29
    相关资源
    最近更新 更多