TaylorMac
TaylorMac

Reputation: 9002

Why does this variable not set in a setTimeout function?

I have a basic textarea:

<textarea id='text_comment'></div>

I have this function:

$('#text_comment').live('keypress', function() {

    setTimeout(function() {
    string = $(this).val();         

         alert(string);
    }, 500);

});

It should alert the value that is in the textarea, but it alerts nothing.

I would like it to get the value of the textarea after 500ms, but it doesn't seem to set the variable if it is inside of the setTimeout function.

Upvotes: 0

Views: 1163

Answers (5)

Guffa
Guffa

Reputation: 700680

Because the callback is not run in the scope of the keypress event, but in the global scope window.

Copy the reference to a local variable so that it's included in the closure:

$('#text_comment').live('keypress', function() {

  var element = this;

  window.setTimeout(function() {
    var string = $(element).val();         
    alert(string);
  }, 500);

});

Upvotes: 1

Quentin
Quentin

Reputation: 944200

The value of this depends on how the current function has been called. The function you pass to setTimeout is a different function to the event handler, so the value of this is different.

Make a copy of this first.

$('#text_comment').live('keypress', function() {
    var that = this;
    setTimeout(function() {
    string = $(that).val();         
         alert(string);
    }, 500);

});

Upvotes: 1

sv_in
sv_in

Reputation: 14049

when 'keypress' event is fired, the value of this in the function would be textarea object. But when the function in setTimeout is run (after 500 milliseconds), the value of this has been changed to something else (perhaps window object)

Change your code to:

$('#text_comment').live('keypress', function() {

    var textarea = this;
    setTimeout(function() {
    string = $(textarea).val();         

         alert(string);
    }, 500);

});

Upvotes: 0

dleavitt
dleavitt

Reputation: 1392

The value of this changes inside the function passed to setTimeout. Do it like this:

$('#text_comment').live('keypress', function() {

    var self = this

    setTimeout(function() {
    string = $(self).val();         

         alert(string);
    }, 500);

});

Upvotes: 1

meder omuraliev
meder omuraliev

Reputation: 186672

context becomes window's since setTimeout is a method of window.

$('#text_comment').live('keypress', function() {

    var el = this;

    setTimeout(function() {
         var string = $(el).val();         

         alert(string);
    }, 500);

});

if you save a reference to the el in this manner you can rely on it instead of this

And also, you can just use el.value since theres no need to wrap it in jQuery and do the exact same thing internally by .val()

Upvotes: 5

Related Questions