1

i am trying to make a timer bar using this code :

var timer =  {
    elem: document.getElementById("myBar"),
    width:0,
    startTimer: setInterval(this.addWidth, 10),
    addWidth : function() {
        this.width += 0.01;
        this.elem.style.width = this.width + '%';
    },
    stopTimer: function() {
        clearInterval(this.startTimer);
        showModal();
    }
}

and here is the html

var newHtml =   '<div id="myProgress">' +
                '<div id="myBar">' +
                '<div id="label"></div>' +
                '</div>' +
                '</div>';

later on i will add this to the document after adding the html to the page and using

timer.startTimer

but it seems that the setInterval() is not working

k961
  • 527
  • 1
  • 5
  • 19
  • @aw04 wrap what ? – k961 Nov 23 '16 at 18:58
  • 1
    'this' is a tricky thing in javascript. You might want to read a bit on [this](http://stackoverflow.com/questions/3127429/how-does-the-this-keyword-work) – Vladimir M Nov 23 '16 at 18:59
  • the `setInterval`. Think of that as a function ... that you are immediately invoking when creating the object rather than a function that starts the timer when it is called. – Damon Nov 23 '16 at 18:59
  • 1
    setInterval(function() { this.addWidth(); }, 10); This will prevent you from losing context of "this" within the addWidth function. – hack3rfx Nov 23 '16 at 19:02
  • @adeneo this duplicate seems wrong, I don't think the intention of this question has anything to do with that problem... even if the literal code makes it seem that way at a glance – aw04 Nov 23 '16 at 19:04
  • 1
    I vote for reopening because `this` is not the main problem here – axelduch Nov 23 '16 at 19:05
  • @aw04 - Seems like that's exactly the problem, using `this` in an object literal without a new scope – adeneo Nov 23 '16 at 19:08
  • @hack3rfx - that won't work, `this` inside the interval will be the global, not the `timer` object. – adeneo Nov 23 '16 at 19:11
  • @adeneo I've built game loops based on this. While it doesn't make sense, "this" will not be global within the setInterval – hack3rfx Nov 23 '16 at 19:12
  • @hack3rfx - really -> https://jsfiddle.net/076r7udo/ – adeneo Nov 23 '16 at 19:13
  • @adeneo the real problem, though, if you assume startTime is meant to start the timer, is not wrapping the setInterval call with a function, which makes it fine... until you get to the addWidth call which of course is a different this problem – aw04 Nov 23 '16 at 19:23
  • @aw04 - seeing as the OP never starts the timer, only stops it, which works fine the way it's written, and wouldn't work if the `setInterval` was wrapped, the real issue seems to be the use of `this` without the proper function scope inside the interval. – adeneo Nov 23 '16 at 19:43
  • @adeneo you're right, my apology. i completely glossed over stopTimer which makes it clear – aw04 Nov 23 '16 at 20:05
  • 1
    Also, so far the answers aren't really fixing an important aspect of this question, startTimer and stopTimer won't work as expected without an extra variable to keep the interval id. So far `this.addWidth` is used as the interval id, which is wrong, the interval id is returned by `setInterval` only, some extra work is needed to get this to work properly I think. – axelduch Nov 24 '16 at 10:20
  • @adeneo - really -> https://jsfiddle.net/u7zjcoyo/ – hack3rfx Nov 28 '16 at 14:50
  • 1
    @hack3rfx - that code has absolutely nothing in common with the OP's code, and isn't even using an object literal. – adeneo Nov 28 '16 at 15:06

2 Answers2

2

It looks like you mean to be setting startTimer to a function reference, but instead you're calling setInterval and setting startTimer to whatever it returns.

You could try

startTimer: function () {setInterval(this.addWidth, 10);},
Mark Adelsberger
  • 32,904
  • 2
  • 24
  • 41
1

If you want the code in the setTimer to property to execute, you have to wrap it in a function:

startTimer: function(){ setInterval(this.addWidth, 10) };

And then you'd call it with:

timer.startTimer(); // Note the parenthesis?

The parenthesis at the end of the statement indicates that you want to execute the function stored in the property.

As it stands now, you have a simple property that is storing the integer returned from the setInterval call.

Scott Marcus
  • 57,085
  • 6
  • 34
  • 54