2

this code works:

var myElement = document.getElementById("red"); 
    setInterval(function() {
        console.log("Left:" + myElement.offsetLeft + "px | Top:" + myElement.offsetTop + "px");
    }, 1000);

This prints out the position(x, y) every second

But If I try and change it to using objects:

function Enemy(id){
    this.id = getElementById(id);
    this.getCoordinates = function(){
        setInterval(function() {
            console.log("Left:" + this.id.offsetLeft + "px | Top:" + this.id.offsetTop + "px");
        }, 1000);
    }
}

$(document).ready(function(){
    var enemy = new Enemy("red");
    enemy.getCoordinates();

});

It prints out nothing - and I can't see where my mistake is.

1
  • 2
    getElementById is not a global function, use document.getElementById Commented Sep 5, 2013 at 20:38

4 Answers 4

4

In a setInterval or setTimeout (or any event handler like onclick) the this variable refers to the global object. In a browser that's window.

In modern browsers you can do this:

setInterval((function() {
        console.log("Left:" + that.id.offsetLeft + "px");
    }).bind(this), 1000); // <------- bind

Otherwise all other solutions are basically similar to your first piece of code.

Note that there is an implementation of bind() in pure js from Mozilla that can be ported to older browsers. Search for it on MDN.

Sign up to request clarification or add additional context in comments.

Comments

2

The problem is that the value of "this" is changing within the setInterval. The fix is to change it to:

function Enemy(id){
  this.id = document.getElementById(id);

  var self = this;
  this.getCoordinates = function(){
    setInterval(function() {
        console.log("Left:" + self.id.offsetLeft + "px | Top:" + self.id.offsetTop + "px");
    }, 1000);
  }
}

1 Comment

You'll want to qualify document.getElementById(), too.
1
function Enemy(id){
    this.id = document.getElementById(id);
    this.getCoordinates = function(){
        var element = this.id;
        setInterval(function() {
            console.log("Left:" + element.offsetLeft + "px | Top:" + element.offsetTop + "px");
        }, 1000);
    }
}

$(document).ready(function(){
    var enemy = new Enemy("red");
    enemy.getCoordinates();

});

Comments

0

As slebetman said, the 'this' variable is not what you expected. Try saving it in a 'that' variable, which can be accessed in different scopes.

function Enemy(id){
    var that = this; // reference to 'this' that can be used in other scopes
    that.id = document.getElementById(id);
    that.getCoordinates = function(){
        setInterval(function() {
            console.log("Left:" + that.id.offsetLeft + "px | Top:" + that.id.offsetTop + "px");
        }, 1000);
    }
    return that;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.