最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

html - javascript function name cannot set as click? - Stack Overflow

programmeradmin7浏览0评论

Below is my code and it doesn't work. After I rename the "click()" to "click1()" it works, why?

<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>

Below is my code and it doesn't work. After I rename the "click()" to "click1()" it works, why?

<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>
Share Improve this question edited Dec 8, 2010 at 15:44 Andy E 345k86 gold badges480 silver badges450 bronze badges asked Dec 8, 2010 at 14:16 micahli123micahli123 4801 gold badge7 silver badges10 bronze badges 2
  • Also note that changing the "onclick" to "window.click()" makes it work – Pointy Commented Dec 8, 2010 at 14:47
  • Thank you all. I'm a beginner. I think I have to speed up my learning at w3school. It's my first post on stackoverflow.. I'm so happy it's very active and kind here. To Pointy: I will try window.click() after I learn more.. – micahli123 Commented Dec 8, 2010 at 15:12
Add a ment  | 

7 Answers 7

Reset to default 17

The string values of "onfoo" handler attributes are interpreted as the bodies of handler functions. In other words, it's as if the string value of the attribute is passed to new Function("event", str) with the result being the handler function used.

Additionally, the lexical scope of the function is established as follows, taken from the HTML5 spec (which I consult only in its capacity of a prehensive description of browser behavior):

Lexical Environment Scope
* Let Scope be the result of NewObjectEnvironment(the element's Document, the global environment).
* If the element has a form owner, let Scope be the result of NewObjectEnvironment(the element's form owner, Scope).
* Let Scope be the result of NewObjectEnvironment(the element's object, Scope).

Thus it's as if there are up to two nested with blocks implicitly wrapped around the code. Thus in this case the effect is that of calling this:

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

Because there's a "click" method on the DOM element corresponding to the <button>, that function is what's called by the handler, not the global one established by the script tag. If the "onclick" attribute is set to "window.click();" then the page works properly.

There's already a function called click, responsible for calling the event handler. By declaring another, you override the first, so the event doesn't work anymore.

See the answer by Pointy for why this happens.

To avoid the issue, there are several options. Since the problem is that a function name will classh with a property name, all revolve around unambiguously referring to the function needed.

Use .addEventListener() (Remended)

This is the most straight forward and conflict free way to register event handlers using JavaScript.

NOTE: If the <script> tag is in the <headd> section or otherwise before the element that is looked up, then the JavaScript code will execute before the element is in the DOM and thus will not be found. See Why does jQuery or a DOM method such as getElementById not find the element? for more information and ways to avoid that. The two easiest ones are moving the <script> section at the end of the body or using defer (when the <script> tag uses the src attribute).

Here is a solution where the <script> tag is moved:

<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>

Use window.yourFunction

This will unambiguously refer to what is is defined in the global scope:

<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>

Drawbacks

One drawback is that there can still be clashes with the same name. This time with something defined in window.

Another drawback is that all other code can also use the global scope, the function might be accidentally overwritten.

Essentially, this solution is only one step removed from the original problem of the name of a function clashing with another name but still vulnerable to the same form of clash.

Rename the function

This will disambiguate the function by making it distinct

<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>

Drawbacks

The new name can still clash with something. If not with a DOM property, then with something from window. And if not now then perhaps later in the future when:

  • a new property is added to HTML
    • this could even be by somebody defining a custom attribute or custom element
  • a new property is added to window
    • again, this could be another script on the page adding it

Essentially, this has a chance to merely delay the problem.

click() is the inbuilt of javascript's button object.

click() a reserved name for a method used in HTML5 http://www.w3/TR/html5/webappapis.html

click is predefined event. You should not use predefined events.

You should perhaps consider using jQuery to refactor your code:

<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./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>
发布评论

评论列表(0)

  1. 暂无评论