2

Here is my code that is not working correctly:

$(document).ready(function() {
    for (var i = 0; i < 3; i++) {
        var bt = new HrButton("btn" + i);                    
        bt.setOnclick(function() {
            alert(bt.name + " clicks = " + bt.cntClick);
            bt.cntClick = bt.cntClick + 1;
        });
        $("#container").append(bt.toHtml());
    }
});

How can I maintain three instances of bt within the function. As it stands now bt refers to btn2 in each onclick.

rChavz
  • 235
  • 3
  • 16

1 Answers1

5

If setOnclick is implemented nicely, you should probably be able to do:

bt.setOnclick(function() {
    alert(this.name + " clicks = " + this.cntClick);
    this.onclick = this.cntClick + 1;
});

Otherwise, you need to create a new scope for each callback function so that they each have their own bt. One way to do that would be:

bt.setOnclick(function(bt){
    return function(){
        alert(bt.name + " clicks = " + bt.cntClick);
        bt.onclick = bt.cntClick + 1;
    };
}(bt));

Comment Response

To implement setOnClick such that this refers to the relevant HrButton (rather than the element) within the callback, you can use the following code (works in modern browsers only, unless you SHIM bind):

var self = this;
self.setOnClick = function(fnOnClick) {
    element.onclick = fnOnClick.bind(self);
};

Since you're using jQuery the following code will be a cross-browser equivalent:

var self = this;
self.setOnClick = function(fnOnClick) {
    element.onclick = $.proxy(fnOnClick, self);
};

Otherwise this will work in all browsers, without any libraries, and is only slightly less readable:

var self = this;
self.setOnClick = function(fnOnClick) {
    element.onclick = function(event) {
        return fnOnClick.call(self, event);
    };
};
Paul
  • 139,544
  • 27
  • 275
  • 264
  • is not really a library, is scenario for learning and how I can made a setOnClick implemented nicely if I have this.setOnClick(fnOnClick) { elemen.onclcik = fnOnCLick; ) where element is create from documente.createElement('button') – rChavz Jul 15 '13 at 17:44
  • @rChavz Is `setOnclick` a function that you wrote yourself? Did either of the above codes solve your problem? – Paul Jul 15 '13 at 17:44
  • @rChavz I updated my answer with a few ways to implement `setOnClick`, so that you can use `this`. – Paul Jul 15 '13 at 17:58
  • so muchas gracias = thanks, one more question why you obfuscate this on self? – rChavz Jul 15 '13 at 19:16
  • 1
    @rChavz It is necessary to make a copy of a reference to the object, so that you can refer to it within the function, since `this` refers to the calling context of the callback function (the `element`), and you want to refer to the `HrButton` which is `this` outside the callback. – Paul Jul 15 '13 at 19:34