2

Should 'this' in the following code not still refer to the DOM object selected by the MooTools selector?

$$('div').addEvent('click', function()
{
    var click1 = function(){$(this).setStyle('background', 'red');}
    click1();
});
Hooked
  • 84,485
  • 43
  • 192
  • 261
Brownbay
  • 5,400
  • 3
  • 25
  • 30

5 Answers5

2

You should do it the MooTools way - by binding this to the click1 function - http://jsfiddle.net/oskar/7EArh/5/

$$('div').addEvent('click', function() {
    var click1 = function() {
        this.setStyle('background', 'red');
    }.bind(this);
    click1();
});​

Also this is already extended with MooTools methods, so there is no need for doing $(this).

Oskar Krawczyk
  • 3,492
  • 17
  • 20
  • 1
    +1 and also, mootools way: `click1.run(args, this);` - > check http://mootools.net/docs/core/Native/Function#Function:run and the other `Function` methods. – Dimitar Christoff Aug 26 '10 at 10:56
2

The cleanest way to handle it is this:

var click1 = function() {
    this.setStyle('background', 'red');
};

$$('div').addEvent('click', click1);

in the above, 'this' get's passed to the function called.

Working example: http://jsfiddle.net/gT5dc/

shanebo
  • 243
  • 1
  • 4
  • 12
0

No. click1() isn't associated with any object (it's not e.g. callable as obj.click1()), so in it this refers to the window.

However, you can do:

click1.call(this);

The call method basically sets this to its first parameter.

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
0

You'll need to do this instead to refer to the element you want:

click1.call(this);

Otherwise this refers to window inside the function, you can see the working version here.

Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • @Downvoter - care to comment? The alternative answer provided is more expensive for this particular example, saying what's *wrong* with this answer might actually help others. – Nick Craver Aug 26 '10 at 11:34
  • Sure, this will work but it's not the MooTools way of doing stuff. Chrys is using a JS framework for a reason. – Oskar Krawczyk Aug 26 '10 at 20:21
  • well, if you are talking expensive, then perhaps the whole thing should be refactored. for example, if the function is not being re-used, there's no sense in saving it. using `$(this)` in mootools is redundant, this is not jquery - especially in the context of a callback from an event where the element would have been extended already. using `.bind` or `.pass` are chainable mootools methods that allow binding+passing of arguments. I would argue `expensive` in the context of an extra function call is not an issue (unless animating)--code legibility+best framework practices are more important. – Dimitar Christoff Aug 27 '10 at 09:23
  • @Dimitar - Using a more expensive route for something that can be done in vanilla JavaScript with the same amount of code is "best framework practices"...really? Neither of you have explained what's *wrong* with the answer, and more importantly, the other answer *fails to answer the question*. The author asked what `this` would be, as he has it, it would be `window` inside his `click1()` call, but the @Oskar's answer failed to mention that. Sure it's a good practice to go that way for *most* things, but you start by answering the question... – Nick Craver Aug 27 '10 at 09:46
  • well, clearly you know your mootools so I will just take your word for it. – Dimitar Christoff Aug 27 '10 at 11:07
  • @Dimitar - You seemed to have missed my point entirely, it's a *JavaScript closure question*, regardless of framework, as it's written, `this` won't maintain context in `call1`...regardless of which framework you're using... – Nick Craver Aug 27 '10 at 11:55
  • no, i have not missed your point but you need to look at the bigger picture. the answer could have simply been `'this' will be window`. the reason why we are having this argument at all is that since mootools is class-centric development, people go out of their way in order to keep `this` referencing the class instance even in event callbacks and achieve it through the '.bind' wrap, amongst other ways. showing how to change scopes is far more useful, imo. anyway - no skin off my nose. – Dimitar Christoff Aug 27 '10 at 12:12
0

In this kind of crazy situation, I just do:

$$('blah').addEvent('click', function() { var self = this;

var click1 = function(){ self.setStyle(....); }
click1();

});

... of course. mostly none of my code would include a click1(); at the end. These kind of inner functions like click1 would normally be used for some other purpose. for e.g.

var click1 = function(){ self.addClass('blah2').removeClass('blah'); } self.set('tween', { onComplete: click1 }).fade('in');