tags:

views:

64

answers:

3

The problem is with object's variable:

this.timer

it's not "global", so when I click the stop button the value of the variable is wrong.
If I declare a global variable MyObject (loke var mytimer;) and use it instead this.timer, it works.

This is my code:

<html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8">
        <title></title>
        <script type="text/javascript" language="JavaScript">               
            var MyObject = {

                init: function(){
                    this.timer = 0;
                    document.getElementById("btn1").onclick = function(){
                        MyObject.RunIt();
                    };
                    document.getElementById("btn2").onclick = function(){
                        clearInterval(this.timer);
                    };

                },

                RunIt: function(){
                    var x=0;
                    this.timer = setInterval(function(){
                x++;
                        document.getElementById("spn").innerHTML=x;
                    }, 1000);

                }

            };


        </script>
        <style type="text/css">
        </style>
    </head>
    <body onload="MyObject.init();">
        <input type="button" id="btn1" value="Run"/>
        <input type="button" id="btn2" value="Stop"/>
        <span id="spn"></span>
    </body>
</html>
A: 
frunsi
That first sentence is absolutely not correct.
Pointy
Is there a workaround using the object declaration that I used?
mariki
mariki: you can put timer into your MyObject declaration, e.g. `var MyObject = { timer:0, ... }`. But the you always have to reference it through MyObject.timer - even in RunIt and the other two functions.
frunsi
@frunsi again, that is simply not correct. There are ways of making it work the way he wants it to.
Pointy
Pointy: it IS hardly correct, with a subtle difference: the `this` in the OPs code refers to the `window` object. So, yes, a `this` is available everywhere, but it does not refer to `MyObject`.
frunsi
@frunsi I suggest you do some reading. It is entirely possible to arrange for the callback to work the way he wants, with the "this" pointer pointing at his object. (Also, the "this" in the original question will NOT refer to the "window" object, it'll refer to the button.)
Pointy
+2  A: 

The problem is this: when you set "onclick" to a function call like that, there's no object reference in the call. The browser calls your function to do the "clearInterval", but "this" is not pointing to your object - in fact, it's pointing at the button element itself.

Here's one way to work around the problem:

var self = this;
document.getElementById('btn2').onclick = function() {
  clearInterval(self.timer);
};

I know that question-askers on Stackoverflow get annoyed sometimes when people urge them to investigate jQuery or some other modern Javascript framework, but it's simply a better way to do things.

Pointy
@Pointy: Regarding your last sentence, that's just your opinion. There are plenty of situations where I think it's preferable not to use one of the big JavaScript libraries.
Tim Down
about jquery maybe you're right, but If i wanted jquery I would added the necessary tag...
mariki
@frunsi, so this answer is also not good?
mariki
Nah, my fault! It is correct.
frunsi
+1  A: 

This is a common problem in writing javascript code; the Scope.

in an .onclick method on an element, the scope (this) is the element itself not the class you are in (MyObject).

i use this/that method; like below:

            init: function(){
                this.timer = 0;
                document.getElementById("btn1").onclick = function(){
                    MyObject.RunIt();
                };

                var that = this;
                document.getElementById("btn2").onclick = function(){
                    /** 
                        Here i use 'that' instead of 'this';
                        because 'this' is the button element
                    */
                    clearInterval(that.timer);
                };

            },
takpar