3

The browser’s console says:

TypeError: status.style is undefined, line 12
var status;
function output(msg,type="info"){
    status.innerHTML=msg;
    switch(type){
        case "info":
            status.style.background=undefined;
            break;
        case "warning":
            status.style.background="#cccc33";
            break;
        case "error":
            status.style.background="#ff0033";
            break;
    }
}
function init(){
    status=document.getElementById("status");
    output("Document loaded","error");
}
window.onload=init;
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" >
        <title>Drag and drop upload</title>
        <link href="css/style.css" rel="stylesheet" type="text/css" >
        <script src="js/script.js" type="text/javascript"> </script>
    </head>
    <body>
        <header>
            <h1>Drag & drop upload</h1>
        </header>
        <div id="main">
            <div id="status">Status</div>
            <div id="inner"> </div>
        </div>
        <footer>&copy; Copyright 2015</footer>

    </body>
</html>

I know this is so simple and basic but I got no other choice but to ask. As I tested I think this is a scope error. So what’s the problem?

Sebastian Simon
  • 14,320
  • 6
  • 42
  • 61
SomeOne
  • 33
  • 3
  • Is this Javascript before or after the HTML is declared? Sometimes, if you call a DOM object before the page is finished, it doesn't declare. – 9Deuce Jul 31 '15 at 19:31
  • I get it. Don’t use `status`… – Sebastian Simon Jul 31 '15 at 19:31
  • thanks Xufox its worked.but why it happened? – SomeOne Jul 31 '15 at 19:34
  • 1
    Consider using [JSFiddle](https://jsfiddle.net/) for questions and answers involving JS, HTML, and CSS. – clesiemo3 Jul 31 '15 at 19:35
  • @SomeOne I posted an answer. That’s a very subtle thing that you stumbled upon… – Sebastian Simon Jul 31 '15 at 19:37
  • @SomeOne I strongly encourage you to use [JSHint.com](http://jshint.com) to validate your JavaScript code in the future. It actually says “Redefinition of `status`.” and “Read only.”; JSHint is a great tool! – Sebastian Simon Jul 31 '15 at 21:05
  • @SomeOne I updated my answer because of two things: there’s another solution to your problem which allows you to use the same variable names and I incorrectly assumed that the weirdness of `window.status` was based on getters and setters — instead it’s based on WebIDL bindings. – Sebastian Simon Aug 10 '15 at 03:46
  • Possible duplicate of [\`var status = true\` can't be set as boolean, why?](https://stackoverflow.com/questions/15788709/var-status-true-cant-be-set-as-boolean-why) – Sebastian Simon Apr 15 '18 at 04:03

1 Answers1

2

You’re not actually referring to your status variable, but to window.status.

There are two possible solutions to this:

  • Simply don’t use status, but another variable name instead, or
  • Wrap your code in an IIFE like this: (function(){…}());

window.status is a special property: it has a WebIDL binding. In this case, this basically means that the value of the property is changed and updated secretly. In the case of window.status, whenever a value is assigned to it, it is turned into a string. That’s why console.log(status) yields the string

"[object HTMLDivElement]"

instead of the element

<div id="status">

And only HTML elements have the style property, not strings. That’s why status.style is undefined.

That’s not an issue if you access an undefined property of a defined value. That’s why status.innerHTML didn’t throw the error. But with status.style.background, you tried to access an undefined property of an undefined value.

If you use immediately invokable function expressions (IIFEs), you can use whichever variable names you want:

(function(){
  var status;
  // etc.
})();

window.status was used to set the status text of a window (back then, when browsers had status bars).

Sebastian Simon
  • 14,320
  • 6
  • 42
  • 61
  • because you are setting a property of the object, not a bug. When you try to read a property that does not exists of an object it has an issue. – epascarello Jul 31 '15 at 19:50