JavaScript函数名不能设置为click吗?

13

以下是我的代码,但它并没有起作用。当我将 "click()" 重命名为 "click1()" 后,它就能正常工作了,请问为什么?

<html>
<head>
    <title></title>
    <script type="text/javascript">
        function click() {
            document.getElementById("content").innerHTML = "abc";
        }
    </script>
</head>

<body>
    <button onclick="click()">try it</button><br />
    <div id="content"></div>
</body>
</html>

我认为没有任何答案充分解释了这个问题。 - Pointy
还要注意将“onclick”更改为“window.click()”才能使其正常工作。 - Pointy
谢谢大家。我是一个初学者。我认为我需要加快在w3school的学习速度。这是我在stackoverflow.com上的第一篇帖子。我很高兴这里非常活跃和友好。对于Pointy:在我学到更多之后,我会尝试window.click()。 - micahli123
7个回答

17

"onfoo"处理程序属性的字符串值被解释为处理程序函数的正文。换句话说,就好像将属性的字符串值传递给new Function("event", str),结果是使用处理程序函数。

此外,根据HTML5规范(我仅在其作为浏览器行为全面描述的能力下进行咨询),函数的词法范围如下所述:

词法环境范围
* 让Scope成为NewObjectEnvironment(元素的文档,全局环境)的结果。
* 如果元素具有表单所有者,则让Scope成为NewObjectEnvironment(元素的表单所有者,Scope)的结果。
* 让Scope成为NewObjectEnvironment(元素的对象,Scope)的结果。

因此,它就像隐式包装了最多两个嵌套的with块一样。因此,在这种情况下,效果类似于调用此函数:

var handler = new Function("event", "with (this) { click(); }");

因为与<button>对应的DOM元素上有一个“click”方法,所以处理程序调用的是该函数,而不是脚本标记建立的全局函数。如果将“onclick”属性设置为“window.click();”,则页面可以正常工作。


1

已经有一个名为click的函数,负责调用事件处理程序。声明另一个函数会覆盖第一个函数,因此事件不再起作用。


这个 "click" 函数在哪里?为什么它在词法作用域中,当浏览器将 "onclick" 属性的字符串值(有效地)传递给 eval() 时? - Pointy
@Pointy:这是元素的一个函数。 - thejh
是的,谢谢 - 答案可以在HTML 5规范中找到,也可能在其他地方。 "onclick"属性的文本被解释为函数体,但具有隐式的with块,引用该元素。如果它在一个<form>中,则该表单也将获得一个隐式的with块。 - Pointy
这很有帮助。我有一个名为“export()”的函数,但是我无法激活它。一直在寻找问题直到发现方法名称是问题所在。谢谢! - Kirk Liemohn

0

查看Pointy的答案,了解出现此问题的原因。

为了避免这个问题,有几个选项。由于问题是函数名称与属性名称冲突,所有解决方法都围绕着明确引用所需的函数。

使用 .addEventListener()(推荐)

这是使用JavaScript注册事件处理程序最直接、最无冲突的方式。

注意:如果<script>标签在<head>部分或其他位置之前查找的元素,那么JavaScript代码将在元素在DOM中之前执行,因此无法找到该元素。有关更多信息和避免这种情况的方法,请参见Why does jQuery or a DOM method such as getElementById not find the element?。最简单的两种方法是将<script>部分移到页面主体的末尾或使用defer(当<script>标签使用src属性时)。

下面是一个将<script>标记移动的解决方案:

<html>
<head>
    <title></title>
</head>

<body>
    <button>try it</button><br />
    <div id="content"></div>
    
    <script type="text/javascript">
        function click() {
            document.getElementById("content").innerHTML = "abc";
        }
        
        document.querySelector("button")
          .addEventListener("click", () => click());
    </script>
</body>
</html>

使用window.yourFunction

这将明确地引用在全局范围内定义的内容:

<html>
<head>
    <title></title>
    
    <script type="text/javascript">
        function click() {
            document.getElementById("content").innerHTML = "abc";
        }
    </script>
</head>

<body>
    <button onclick="window.click()">try it</button><br />
    <div id="content"></div>
</body>
</html>

缺点

一个缺点是仍然可能会出现相同名称的冲突。这次是与在window中定义的内容发生冲突。

另一个缺点是所有其他代码也可以使用全局作用域,函数可能会被意外覆盖。

本质上,这个解决方案只是将函数名称与另一个名称冲突的原始问题移开了一步,但仍然容易受到相同形式的冲突的影响。

重命名函数

这将通过使其不同来消除函数的歧义。

<html>
<head>
    <title></title>
    
    <script type="text/javascript">
        function myClick() {
            document.getElementById("content").innerHTML = "abc";
        }
    </script>
</head>

<body>
    <button onclick="myClick()">try it</button><br />
    <div id="content"></div>
</body>
</html>

缺点

新名称仍可能与某些内容冲突。如果不是与 DOM 属性冲突,那么可能会与 window 中的某些内容冲突。而且,如果不是现在,将来也可能会出现以下情况:

  • 向 HTML 添加新属性
    • 这甚至可以通过定义自定义属性或自定义元素的人来完成
  • window 添加新属性
    • 同样,这可能是页面上另一个脚本添加的

实质上,这只是延迟了问题的出现。


-1

click() 是 JavaScript 中按钮对象的内置函数。


-3

你或许应该考虑使用jQuery来重构你的代码:

<html>
<head>
    <title></title>
</head>

<body>
    <button id="button1">try it</button><br />
    <div id="content"></div>
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
    <script type="text/javascript">
        $(document).ready(function() {
            $("#button1").click(function() {
                $("#content").html("abc");
            });
        });
    </script>
</body>
</html>

2
谢谢你的教程。我认为我需要学习jQuery,因为我已经学了一些javascript。感谢您在使用Google服务器上的jQuery文件方面的指导,而不是我的服务器。 - micahli123

-3

-3

click是预定义事件。您不应该使用预定义事件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接