首页 > 解决方案 > onclick 调用了哪个规范化函数?

问题描述

背景:我正在尝试学习一些 JavaScript 和 HTML。我有一些数组,想对它们进行规范化,以便它们的条目总和为 1。为此,我定义了一个名为 normalize 的函数(它以一个数组作为其参数)。在我尝试将对我的 normalize 函数的调用作为按钮单击的一部分合并到我的主 .html 文件中之前,一切都运行良好。下面是一个工作虚拟示例,其中省略了数组内容。

<script>
    function normalize () {return 1;};
</script>
    
<input type="button" onclick="console.log(normalize()); //prints undefined when clicked">

<script>
    console.log(normalize()); // prints 1 as intended
</script>

但是,如果我将函数的名称更改为 normalize 以外的名称,那么两个调用都可以正常工作:

<script>
    function foo () {return 1;};
</script>
    
<input type="button" onclick="console.log(foo()); //prints 1 when clicked">

<script>
    console.log(foo()); // prints 1
</script>

我的问题是:为什么当函数命名为 normalize 时,onclick 调用的行为会有所不同?鉴于 onclick 似乎在我的一个数组上调用了一些外部规范化函数,我本以为它会抛出错误或其他东西。我快速搜索了其他 normalize 函数,我确实看到有一个 HTML DOM normalize 方法,但我不明白为什么它被调用(如果它被调用!)而不是我想要的函数。onclick normalize 调用发生了什么?

提前感谢您提供的任何帮助!

标签: javascripthtmlforms

解决方案


这是不使用onxyz-attribute-style 事件处理程序的众多原因之一:它们在多重嵌套代码中执行,该代码在范围内具有许多对象方法。在这种情况下,您不小心运行Node.prototype.normalize了 ,您可以看到它存在:

console.log("normalize" in Node.prototype);

我们甚至可以看到这是您的按钮正在使用的那个:

<input type="button" onclick="console.log(normalize === Node.prototype.normalize)">

Node.prototype.normalize方法(引用上面的MDN链接)...

...将指定节点及其所有子树放入“规范化”形式。在规范化子树中,子树中没有文本节点是空的,也没有相邻的文本节点。

改为使用addEventListener,这样

  1. 您的函数不必是全局的,并且

  2. 您的代码没有在一个奇怪的范围内运行,有很多很多东西要与之冲突

 function normalize () {return 1;};
 
 document.getElementById("the-button").addEventListener("click", () => {
    console.log(normlize()); // Prints 1
 });
<input type="button" id="the-button" value="Click Me">

getElementById在该示例中使用了 ID,但您不必为此使用 ID。您只需要能够使用任何 CSS 选择器和querySelectoror来识别元素querySelectorAll


推荐阅读