Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access class attribute in event handler in js-mootools

I have a JS object (working with mootools) wich has stored some DOM elements and attach to them event listeners:

window.myObject = {
    init: function(el1ID, el2ID){
        this.myElement1 = document.getElement(el1ID); 
        this.myElement2 = document.getElement(el2ID);

        this.myElement1.addEvents({
            'click' : function(){
                 myObject.myElement2.innerHTML("foo");
             }
        });
    }

}

Now, this works only if i had only one object myObject in the page. I have to create another object for another structure el1ID-el2ID and I would like to make this object a class and instantiate an object for every structure, in order to keep every event handling independent from the others. My problem is: how can I access in the event handler the attributes of the myObject object?

'click' : function(){
    myElement2.innerHTML("foo")
 }

won't work and

'click' : function(){
    this.myElement2.innerHTML("foo")
 }

would search for myElement2 as a property of myElement1 (aka the event raiser). What can I do in stead of accessing staticly the properties of my object?

like image 251
Federinik Avatar asked Mar 24 '26 14:03

Federinik


1 Answers

Click event callbacks are Element-centric and will trigger with the Element as the execution context, i.e. this === myObject.myElement1 in this:

    this.myElement1.addEvents({
        'click' : function(){
             myObject.myElement2.innerHTML("foo");
         }
    });

there is no Element.prototype.innerHTML() method in MooTools, btw. It's Element.prototype.set and is used as el.set('html', someString);. Used to be .setHTML() in 1.1x

To be able to access your object, you have several patterns.

    this.myElement1.addEvents({
        'click' : function(e){
             this.set('html', 'foo');
         }
    });

To access the parent object, you can either rebind or save a reference in a variable instead:

    this.myElement1.addEvents({
        'click' : function(e){
             // this === myObject
             this.myElement2.set('html', 'foo');
             // getting to original
             e.target === this.myElement1; // from event object, like currentTarget
         }.bind(this) // <-- binding to outer object instead
    });

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

A better (arguably, I prefer it a lot of the time to binding due to unbinding event handlers) pattern is to save the reference:

init: function(){
    var self = this;
    ...
    this.myElement1.addEvents({
        'click' : function(e){
             // self is orig. this === self.myElement1;
             self.myElement2.set('html', 'foo');
         }
    });
}

That's about it.

like image 172
Dimitar Christoff Avatar answered Mar 28 '26 01:03

Dimitar Christoff



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!