Използване на $(this) в дъщерна анонимна функция

Опитвам се да използвам $(this) в анонимна функция, за да мога да извикам две анимации едновременно. Преди да поставите анимациите във функцията, тя работеше, но след като ги поставите във функцията $(this) изглежда е извадена от обхвата...

$('#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();
    })

})

Защо $(this) става #document?

Редактиране:
За онези от вас, които четат това и казват, че „това няма нищо общо с едновременното възпроизвеждане на анимации“, сте прави. Решението на този проблем е да използвате queue: false


person nipponese    schedule 22.07.2013    source източник
comment
$(function(){} е еквивалентно на $(document).ready(), следователно #document   -  person Dom    schedule 23.07.2013
comment
Само мисъл, но могат ли хората, публикуващи отговорите, базирани на „кеширане на променливата“, да прочетат отново въпроса? По същество това е „защо се случва това“, а не „как мога да заобиколя това“.   -  person David says reinstate Monica    schedule 23.07.2013


Отговори (6)


$(function(){}) е еквивалентно на $(document).ready(function(){}), което очевидно получава контекст на document.

Предлагам напълно да премахнете $(function(){, защото почти никога не е необходим вътре в събитие.

$('#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();    
});

Единствената причина, поради която трябва да изчакате dom да бъде готов вътре в събитие, е ако задействате споменатото събитие директно преди документът да е готов. Много малко вероятно е потребителят да може да задейства събитието, преди DOM да е готов, освен ако вашият DOM не е абсурдно голям.

person Kevin B    schedule 22.07.2013

защото това:

$(function(){

е еквивалентно на:

$(document).ready(function(){

Прикачване на готов манипулатор към document. Вътре в този манипулатор this е document.

person James Montagne    schedule 22.07.2013

Това:

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

е синоним на:

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

Това е различно от анонимна функция, която изглежда по следния начин:

(function(){
    // ...
})();
person indot_brad    schedule 22.07.2013

Във външната функция направете това...

var self = this;

След това в дъщерната функция използвайте self вместо this

person Hades    schedule 22.07.2013

Просто кеширайте първото това.

$('#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();
    })

})
person Adam Merrifield    schedule 22.07.2013

Това се очаква с контекстния обхват на Javascript. this се отнася до контекста, от който е извикан въпросът. Пример:

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();

Има няколко начина да го заобиколите:

Кръстосан браузър:

$('#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();
    })

})

Кръстосан браузър с помощта на 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))

})

Съвременни браузъри, използващи 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))

})
person Paul    schedule 22.07.2013