为啥在带有括号的 Javascript 事件处理函数中?
Posted
技术标签:
【中文标题】为啥在带有括号的 Javascript 事件处理函数中?【英文标题】:Why in Javascript event handler functions with parentheses?为什么在带有括号的 Javascript 事件处理函数中? 【发布时间】:2013-12-27 10:27:55 【问题描述】:javascript高手,看看这段代码:
<button onclick="handler()">ClickMe</button>
<script>
function handler()
alert("clicked");
</script>
为什么 onclick 事件应该分配给带有 () onclick="handler()" 的处理程序? 在这种情况下,警报被调用。但根据描述为类似问题https://***.com/a/3247044/2543590onclick 的答案的逻辑,分配给函数处理程序的结果,而不是函数本身。 我相信将 onclick 分配给功能应该是这样的
onclick="handler",
但在这种情况下警报不会被调用。 为什么?
【问题讨论】:
JavaScript 专家会告诉你不要在标记中绑定内联事件处理程序。 一个使用内联处理程序有用的例子是当你需要确保元素可用和元素完全正常运行之间没有延迟。这不会经常发生,但内联处理程序很好地解决了这个问题。大师会告诉你使用正确的工具来完成这项工作。 “大师”会告诉您了解不同设计决策的后果,然后根据一些“最佳”标准选择最适用于某种情况的决策。 【参考方案1】:内联 JS
当您执行这样的内联 onclick 处理程序时,您正在分配一个要运行的 Javascript 表达式。所以你需要执行这个函数。
表达式可以很容易地成为onclick="handler();alert(2)"
,在这种情况下,很明显需要调用该函数,就像从 javascript 文件中运行它一样。
将函数绑定到点击事件
如果你用javascript附加点击事件,你将绑定一个函数,所以你只需要传递函数对象。
var btn = document.getElementById("btn");
btn.addEventListener("click",handler);
addEventListener
设置要绑定到事件的函数对象,以便在事件触发时执行。由于您指定的是函数对象,而不是字符串表达式,因此不需要括号。事实上,如果你添加它们,函数将立即执行,函数的返回值将绑定到事件。
最佳实践
一般来说,大多数人会提倡你在 javascript 中通过绑定函数处理程序而不是使用内联 JS 来绑定事件。它更易于调试,不会将您的逻辑紧密绑定到 DOM,并且对于动态页面更灵活。它还强制您创建任何您调用的全局函数。
总结
关键是指向一个字符串的属性,该字符串被评估为一个JS表达式,它与将函数对象绑定到事件不同。
【讨论】:
我会挑剔一点。拥有一个函数调用并没有真正将逻辑绑定到 DOM,就像在元素上拥有一个类以在 DOM 加载后绑定处理程序一样。我同意,对于最常见的情况,内联处理程序并不是最好的方法,但有时它们非常有用。 @BlueSkies 确实如此。如果你有一个类,你可以在不改变 DOM 的情况下改变功能。如果你有内联函数,你就不能在不改变 DOM 的情况下改变表达式。因此它的绑定更紧密。 如果您更改 DOM,可能是您需要更改 DOM 选择,该选择为处理程序分配选择元素。两种方式都不是完全纯粹的。【参考方案2】:因为 onclick="handler"
不是 JavaScript。这是您的标签的一个属性。是的,如果这是 JavaScript,您将能够传入函数本身,但事实并非如此;您正在分配一个 statement 在点击时执行。
onclick="handler"
执行的语句基本上是这样做的:
<script>
handler;
</script>
IE,什么都没有。
【讨论】:
它是javascript,这就是为什么你放脚本标签...【参考方案3】:元素上的所有on
-属性实际上设置了内联Javascript,而不是处理程序。所以你实际上是在那里执行代码,在这种情况下是一个函数调用。如果省略括号,则只是无效代码。
比较:
<button onclick="alert('click!')">Click me!</button>
【讨论】:
再举个例子让他更清楚,比如onclick="var t=1;alert(t);t++;alert(t);"
【参考方案4】:
你放在onclick=""
中的任何东西都将被一个隐式函数包裹。 那 是点击时调用的实际事件处理程序,它里面的任何函数调用都需要括号。
【讨论】:
以上是关于为啥在带有括号的 Javascript 事件处理函数中?的主要内容,如果未能解决你的问题,请参考以下文章
在 JavaScript 事件处理中,为啥“return false”或“event.preventDefault()”和“停止事件流”会有所不同?
为啥我在使用 javascript 自动完成时在 Eclipse 中收到消息:“未处理的事件循环异常 Java 堆空间”?