JavaScript/jQuery: $(this) with setTimeout

hankknight
hankknight used Ask the Experts™
on
The value of $(this) is lost when I pass it using setTimeout:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Demo</title>

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<script type="text/javascript">

$(document).ready(function() {
 $('#xyz').click(function(index) {
  alert($(this).attr('id'));
  setTimeout("alert ($(this).attr('id'));",2000);
 });
});

</script>
</head>
<body>

<p>
<input type="button" value="Click Here" id="xyz" />
</p>

</body>
</html>

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Expert of the Year 2008
Top Expert 2008
Commented:
Currently, on your setTimeout call, your first argument is a string:
"alert ($(this).attr('id'));"

Instead of a string:
a. save a reference to "this" on some variable -ex: var self=this
b. pass an anonymous function using the variable reference:

<script type="text/javascript">

$(document).ready(function() {
 $('#xyz').click(function(index) {
  alert($(this).attr('id'));
  var self=this;
  setTimeout(function(){alert ($(self).attr('id'));},2000);
 });
});

</script>

Open in new window

You just need to refactor it a bit:

$('#xyz').click(function(index) {
    alert($(this).attr('id'));
    setTimeout((function() {
        alert($(this).attr('id'));
    }).apply(this), 2000);
});

Open in new window

Author

Commented:
Proculopsis, your idea looks interesting but it does not work.  The alert is instant instead of delayed:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Demo</title>

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<script type="text/javascript">

$(document).ready(function() {
 $('#xyz').click(function(index) {
    setTimeout((function() {
        alert($(this).attr('id'));
    }).apply(this), 2000);
 });
});

</script>
</head>
<body>

<p>
<input type="button" value="Click Here" id="xyz" />
</p>

</body>
</html>

Open in new window

I missed that, try this instead:

$('#xyz').click(function(index) {
    alert($(this).attr('id'));
    setTimeout(new timedEvent(this).action, 2000);
});

function timedEvent(element) {

    this.action = function() {
        alert($(element).attr('id'));
    }

    return this;
}

Open in new window

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial