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

javascript - Why can't I call a function named clear from an onclick attribute? - Stack Overflow

programmeradmin8浏览0评论

i'm trying to create a simple calculator, when a button is clicked its value is shown in the text field and the button "C" should clear the text field but its onclick="clear()" is not working??

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Calculator</title>
        <style>
            #button{
                padding: 10px;
            }
        </style>
        <script>
            function fill(val){
                document.getElementById("field").value+=val;
            }
            function clear(){
                document.getElementById("field").value="";
            }
        </script>
    </head>
    <body>
        <form>
        <table>
            <tr><input type="text" name="field" id="field" size="8"/></tr>
        <%! int k = 1; %>
        <% for(int i=0;i<3;i++){ %>
        <tr> <%
            for(int j=0;j<3;j++){ %>
            <td><input type="button" id="button" onclick="fill(this.value)" value="<%=k++%>" /></td>
          <%  } %>
        </tr>
        <% } %>
        <tr>

<!--here onclick="clear()" is not working?? -->

            <td><input type="button" id="button" value="C" onclick="clear()"/></td>
            <td><input type="button" id="button" value="0" onclick="fill(this.value)"</td>
            <td><input type="submit" id="button" value="="</td>
        </tr>
        </table>
        </form>
    </body>
</html>

i'm trying to create a simple calculator, when a button is clicked its value is shown in the text field and the button "C" should clear the text field but its onclick="clear()" is not working??

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Calculator</title>
        <style>
            #button{
                padding: 10px;
            }
        </style>
        <script>
            function fill(val){
                document.getElementById("field").value+=val;
            }
            function clear(){
                document.getElementById("field").value="";
            }
        </script>
    </head>
    <body>
        <form>
        <table>
            <tr><input type="text" name="field" id="field" size="8"/></tr>
        <%! int k = 1; %>
        <% for(int i=0;i<3;i++){ %>
        <tr> <%
            for(int j=0;j<3;j++){ %>
            <td><input type="button" id="button" onclick="fill(this.value)" value="<%=k++%>" /></td>
          <%  } %>
        </tr>
        <% } %>
        <tr>

<!--here onclick="clear()" is not working?? -->

            <td><input type="button" id="button" value="C" onclick="clear()"/></td>
            <td><input type="button" id="button" value="0" onclick="fill(this.value)"</td>
            <td><input type="submit" id="button" value="="</td>
        </tr>
        </table>
        </form>
    </body>
</html>
Share Improve this question edited Aug 26, 2015 at 22:27 Quentin 944k132 gold badges1.3k silver badges1.4k bronze badges asked Jul 24, 2015 at 14:57 Arpit TomarArpit Tomar 1751 silver badge10 bronze badges 8
  • 2 You have a client side problem. Don't show us server side code. Get the HTML output. – Quentin Commented Jul 24, 2015 at 14:58
  • You aren't closing the button tag. The wonky syntax highlighting should be a clue – Turnip Commented Jul 24, 2015 at 14:58
  • 3 Your HTML is invalid. Use validator.w3/nu – Quentin Commented Jul 24, 2015 at 14:59
  • 1 Well, as far as I can see your last two inputs are a disaster: the first one is not closed, while the second one is not closed and has a caotic value: value="=", you should start by fixing these first. – briosheje Commented Jul 24, 2015 at 14:59
  • 1 Use different Ids. Thats why it called id. Put your script at the body end and not in the head. Some times you trigger someting that not load (body) yet. – Onaiggac Commented Jul 24, 2015 at 15:02
 |  Show 3 more ments

3 Answers 3

Reset to default 19

Intrinsic event attributes (like onclick) are horrible. Internally they implement with:

Use of the with statement is not remended, as it may be the source of confusing bugs and patibility issues.

Consequently, you are actually calling document.clear() instead of your global clear().

The quick fix for this is to rename the function to something else or explicitly call window.clear().

The better solution is to bind your event handlers with addEventListener instead of intrinsic event attributes.

Your HTML has problems, but the reason your function is not working is because of its name "clear", which is already defined by document.clear().

Change the name of that function to something like clearField() and it will work.

clear is a reference to a (deprecated) document.clear function. This has precedence to (shadows) the function you created, because of the scope that is created specifically for onXXXXX attributes in HTML.

This peculiar scope is only active in the script that is provided to this attribute. As soon as execution moves into the JavaScript code that is defined in script tags, this scope "overload" is gone.

So for instance, your code would work again, if you would first call another function, and then let that function call your clear function. Like so:

function clear() {
    alert("my clear() was called");
}

function helper() {
    clear();
}
<button onclick="helper()">Clear!</button>

Background / Source

The scope that is created for executing the script that is passed to an onXXXX attribute is defined in the HTML Standard:

scope

  1. Let realm be settings object's Realm.
  2. Let scope be realm.[[GlobalEnv]].
  3. If eventHandler is an element's event handler, then set scope to NewObjectEnvironment(document, true, scope). (Otherwise, eventHandler is a Window object's event handler.)
  4. If form owner is not null, then set scope to NewObjectEnvironment(form owner, true, scope).
  5. If element is not null, then set scope to NewObjectEnvironment(element, true, scope).
  6. Return scope.

These steps describe how the scope is defined, and this includes which identifiers are bound to which properties. And so we see in step 3 that document is added to the scope, which means that document properties bee accessible via global names. Similarly, the scope may be extended further. For instance, in step 5, the element's properties also bee accessible as globals.

Here is an example of that latter point:

var id = 12; // global variable
console.log(id); // 12
<button id="this-is-me" onclick="console.log(id)">click me</button>

Conclusion

This scope issue can be confusing, certainly when document is an object with many (and many obscure) properties.

All the more reason to avoid using onXXX attributes in your HTML. Best practice is to add event handlers in the main script, using addEventListener.

发布评论

评论列表(0)

  1. 暂无评论