rib3ye
rib3ye

Reputation: 2923

Using $(this) in child anonymous function

I'm trying to use $(this) inside an anonymous function so that I can call two animations at the same time. Before putting the animations in the function, it worked, but after putting them inside the function $(this) seems to be taken out of scope...

$('#chat_input input').focusin(function(event){
    console.log(this); //prints correct input element

    $(function(){
        console.log(this); //prints "#document"
        $(this).transition({width: 840, duration: 200, paddingLeft: 60});
        $('.target').fadeIn();
    })

})

Why does $(this) become #document?

Edit:
To those of you reading this and saying "this has nothing to do with playing concurrent animations," you're right. The solution for that problem is to use queue: false

Upvotes: 1

Views: 113

Answers (6)

egbrad
egbrad

Reputation: 2417

This:

$(function(){
    //...
});

is synonymous with:

$(document).ready(function(){
    //...
});

This is different from an anonymous function which looks something like this:

(function(){
    // ...
})();

Upvotes: 1

Kevin B
Kevin B

Reputation: 95022

$(function(){}) is equivalent to $(document).ready(function(){}), which obviously gets a context of document.

I suggest completely removing $(function(){ because it's almost never needed inside of an event.

$('#chat_input input').focusin(function(event){
    console.log(this); //prints correct input element    
    console.log(this); //prints correct input element (duh)
    $(this).transition({width: 840, duration: 200, paddingLeft: 60});
    $('.target').fadeIn();    
});

The only reason you would need to wait for the dom to be ready inside an event is if you are triggering said event directly before the document is ready. It's very unlikely that the user would be able to trigger the event before the DOM is ready unless your DOM is absurdly large.

Upvotes: 4

Paul
Paul

Reputation: 141827

That is expected with Javascript context scope. this refers to the context that the question was called from. Example:

var myfunc = function(){
    console.log(this);
};

var a = ['a'];
var b = ['b'];
var c = ['c'];

a.myfunc = myfunc; // ["a", myfunc: function]
b.myfunc = myfunc; // ["b", myfunc: function]
c.myfunc = myfunc; // ["c", myfunc: function]

a.myfunc();
b.myfunc();
c.myfunc();

There are a few ways around it:

Cross-browser:

$('#chat_input input').focusin(function(event){
    console.log(this); //prints correct input element

    var self = this;

    $(function(){
        console.log(self);
        $(self).transition({width: 840, duration: 200, paddingLeft: 60});
        $('.target').fadeIn();
    })

})

Cross-browser using jQuery.proxy:

$('#chat_input input').focusin(function(event){
    console.log(this); //prints correct input element

    $($.proxy(function(){
        console.log(this); //prints "#document"
        $(this).transition({width: 840, duration: 200, paddingLeft: 60});
        $('.target').fadeIn();
    }, this))

})

Modern browsers using Function.prototype.bind:

$('#chat_input input').focusin(function(event){
    console.log(this); //prints correct input element

    $((function(){
        console.log(this); //prints "#document"
        $(this).transition({width: 840, duration: 200, paddingLeft: 60});
        $('.target').fadeIn();
    }).bind(this))

})

Upvotes: 0

James Montagne
James Montagne

Reputation: 78650

Because this:

$(function(){

is equivalent to:

$(document).ready(function(){

Attaching a ready handler to the document. Inside that handler, this is the document.

Upvotes: 1

Adam Merrifield
Adam Merrifield

Reputation: 10407

Just cache the first this.

$('#chat_input input').focusin(function(event){
    console.log(this); //prints correct input element
    var $this = $(this);

    $(function(){
        console.log($this); //prints "#document"
        $this.transition({width: 840, duration: 200, paddingLeft: 60});
        $('.target').fadeIn();
    })

})

Upvotes: 0

Hades
Hades

Reputation: 1985

In the outer function do this...

var self = this;

Then within the child function use self instead of this

Upvotes: 0

Related Questions