user1019490
user1019490

Reputation: 11

setTimeout within function fails

This function accepts an argument, whichImage. This is the object HTMLImageElement for the image we are working with. The image width will be halved, and then after 3 seconds, it will return to normal width. However, the setTimeout code, which is supposed to execute after 3 seconds, fails, with the error message that whichImage is not defined. What do I need to correct to make this function work?

function resizeImageFunction(whichImage){
    // Get the width of the image
    alert(whichImage);
    var width = whichImage.width;
    var halfwidth = Math.round(width/2);
    whichImage.width=halfwidth;
    setTimeout("whichImage.width=width;",3000);
}

Upvotes: 0

Views: 798

Answers (5)

jfriend00
jfriend00

Reputation: 707326

The explanation for your problem is as follows:

When you pass a string to setTimeout(), that string will be evaluated by eval() in the global scope. Thus any function you call or variable you reference there must be available from the global scope. That explains why you can't reference a local variable or an argument to your function because neither or those are in the global scope so when eval() tries to find them, it looks in the global scope and they aren't there.

When you change the setTimeout() function to this using an inline anonymous function:

setTimeout(function() {
    whichImage.width = width;
}, 3000);

now you have real javascript code (not a string) that is evaluated in place where it exists with no use of eval() and because of closures you have full access to the local variables and arguments of the enclosing function which gives you access to both whichImage (an argument) and width (a local variable) so your code works.

This is reason #14 which you should always use real javascript function references or anonymous function declarations instead of passing a string to setTimeout().

Upvotes: 1

Starx
Starx

Reputation: 78991

You don't need to use eval for this

setTimeout(function() { whichImage.width=width; } ,3000);

Here is is your function

function resizeImageFunction(whichImage){
    var halfwidth = Math.round(width/2);
    whichImage.width=halfwidth;
    setTimeout(function() { whichImage.width=width; } ,3000);
}

Upvotes: 0

Sudhir Bastakoti
Sudhir Bastakoti

Reputation: 100175

Try:


setTimeout(function() {
   whichImage.width=width;
},3000);   

Upvotes: 0

David Peden
David Peden

Reputation: 18434

You need to wrap your block of code in an anonymous function like:

setTimeout(function () {
    whichImage.width=width;
}, 3000);

Upvotes: 0

Joseph
Joseph

Reputation: 119847

function resizeImageFunction(whichImage){
    // Get the width of the image
    alert(whichImage);
    var width = whichImage.width;
    var halfwidth = Math.round(width/2);
    whichImage.width=halfwidth;

    setTimeout(function(){
        whichImage.width=width;
    },3000);
}

Upvotes: 0

Related Questions