1

Here is the nature of my problem:

function theObject(){
    this.theMethod = function(theParameter){
    //code that uses theParameter
    }

    this.anotherMethod = function(){
        for(var x = 0; x < 10; x++){
            document.writeln("<img src = 'loc.jpg' onclick ='" + this + ".theMethod(" + x  + ")'>");
        }
    }

I think it's pretty straightforward to see what I'm trying to do here...but it doesn't work. The HTML doesn't know what any of my "classes" are. I've tried many variations, including using getElementById().addEventListener() but with that route the for loop variable changes out from under me.

How do you do this? NO jquery please AND "theMethod" must remain encapsulated.

Thanks

3
  • Look at the generated HTML: you're turning this into a string. Don't. Commented Oct 12, 2013 at 5:36
  • Avoid writeln, try innerHTML or appendChild then add the event in JavaScript not in a string. Commented Oct 12, 2013 at 5:37
  • 1
    You cant use 'this' in more than one level of nesting functions Commented Oct 12, 2013 at 5:38

3 Answers 3

1

This should work well for you. Here's a working demo

function theObject(){

  this.theMethod = function(theParameter){
    //code that uses theParameter
  };

  this.anotherMethod = function(){
    for(var x = 0; x < 10; x++){
      var img = document.createElement("img");
      img.src = "loc.jpg";
      img.onclick = this.theMethod.bind(this, x);
      document.appendChild(img);
    }
  }
}

Using Function.prototype.bind requires ECMAScript 5 or higher. If you need to support old dinosaur browsers, please look into es5-shim

If you still can't support .bind, @6502's answer is your next best bet.

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

Comments

1

You cannot use strings to set up events that work on closures; the correct way is instead:

for (var x= 0; x < 10; x++) {
    var img = document.createElement('img');
    img.src = "loc.jpg";
    img.onclick = (function(self,x){
                       return function(){
                           self.theMethod(x);
                       }
                   })(this,x);
    document.appendChild(img);
}

I understand that the code seems convoluted and introduces self but this unfortunately necessary in Javascript because this is not just a regular local variable and because there is no local scope but only function scope.

Without this double wrapping trick (used often in Javascript) all the images would call the method passing the same value instead of the image index.

When you set up an event handler using a string the code will be evaluated in the global scope so in general it's impossible to have that code to use local variables. Moreover objects (like the current object reference by this in the constructor) and closures cannot be converted to string and parsed from strings.

Comments

0

I have a suspicion that turning function theObject = new function(){ into var theObject = new function(){ will fix your problem.

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.