【问题标题】:Why do square brackets around HTML-bound event handlers work?为什么 HTML 绑定事件处理程序周围的方括号有效?
【发布时间】:2020-06-03 01:00:04
【问题描述】:

考虑以下代码 sn-p。

function func1() {
  console.log('func1 fired');
}

function func2() {
  console.log('func2 fired');
}
<button onclick="[[[func1(), func2()]]]">Click Me</button>

请注意,onclick 事件属性的值被多对方括号包围(我任意使用了三个,但括号的数量似乎无关紧要)。该代码在 Firefox 和 Chrome 中有效,但 为什么 有效?这个标准是在某处记录的,还是只是浏览器试图提供帮助。

【问题讨论】:

  • 虽然从理解 JS 如何在 HTML 上下文中执行而言,这是一个非常有趣的问题,但实际上:不要使用 onclick,也不要教 onclick。在加载了 defer 属性的脚本中获取 JS 端的那个按钮(是的,甚至旧 IE 版本也支持)并改用 button.addEventListener("click", ...)
  • 它也适用于<button onclick="[[[[[[[[[[[[func1(), func2()]]]]]]]]]]]]">Click Me</button>
  • @Mike'Pomax'Kamermans 我实际上并没有使用它,也许我应该在问题中指出它。我实际上在 [another question] (stackoverflow.com/a/54154706/3977276) 中发现了这个 sn-p,它激起了我的兴趣。

标签: javascript html


【解决方案1】:

浏览器将从属性值构造一个函数,使用属性的文本作为函数的代码。在你的情况下,这将是一个看起来像

的函数
function madeByBrowser(event) {
  [[[ func1(), func2() ]]];
}

这是合法的 JavaScript。该函数包含一个表达式,一个数组初始值设定项。评估该数组初始值设定项的副作​​用是调用这两个函数。

(实际构造的函数不会完全那样,关于函数中代码的隐式范围有一些奇怪且经常有问题的细节。它已经足够接近了这个问题。)

【讨论】:

    【解决方案2】:

    之所以有效,是因为表达式可以用作 JavaScript 中的语句。所以它创建了函数调用结果的嵌套数组,但不对这些数组做任何事情。

    出于同样的原因,你可以这样写:

    function func3() {
        [[[func1(), func2()]]];
    }
    func3();
    

    【讨论】:

    • 感谢您的回复。对我来说没有意义的是为什么函数func1func2 在页面加载时没有被调用。简单地写[func1(), func2()] 会导致两个函数立即被调用,那么为什么当连接到事件侦听器属性时没有立即调用该函数呢?
    • 因为在您点击之前,onclick 中的任何代码都不会运行。
    • 为什么你认为它是不同的,因为它们在一个数组中? onclick="func1(); func2()" 在您单击之前不会运行这些函数。
    • 是的,我想这是有道理的。再次感谢。
    猜你喜欢
    • 2014-10-22
    • 2016-06-04
    • 2013-12-27
    • 1970-01-01
    • 2021-12-13
    • 1970-01-01
    • 2016-04-21
    • 1970-01-01
    • 2012-08-01
    相关资源
    最近更新 更多