Yugal Jindle
Yugal Jindle

Reputation: 45656

Function is defined, but Error says.. Function is not found ! (Strange)

This is my code :

function mark()
{
    alert("This is a test box..");
}

setTimeout("mark()",5000);

Error : Function mark() is not found !!

There is some other issue.. as it works on http://jsfiddle.net/russcam/6EXa9/ but its not working in my application.. so can you help me debug this ?

What else can be the reason.. By the way I am running this inside a GreaseMonkey script !

Upvotes: 5

Views: 4938

Answers (5)

meouw
meouw

Reputation: 42140

If you are using GreaseMonkey, any functions you define are sandboxed by GM and not available in the main window.
When you use any of the native functions however, like setTimeout or alert, they are called in the context of the main window e.g; when you call setTimeout you are actually calling window.setTimeout()

Now the function you have defined, mark doesn't exist in the main window and what you are asking setTimeout to do is evaluate the string 'mark()'. When the timeout fires window.eval( 'mark()' ) is called and as discussed, window.mark is not defined. So you have a couple of options:

1) Define mark on the window object. GM allows you to do this through the unsafeWindow object like this:

unsafeWindow.mark = function(){}
setTimeout( 'mark()', 10 );        //this works but is ugly, it uses eval

2) Pass a reference to the local mark to setTimeout:

function mark(){}
setTimeout( mark, 10 );        //this works too but you can't send parameters

But what if you need to send parameters? If you have defined your function on the main window, the eval method will work (but it is ugly - don't do it)

unsafeWindow.mark2 = function( param ) {
    alert( param )
}
setTimeout( 'mark2( "hello" )', 10 ); //this alerts hello

But this method will work for functions with parameters whether you have defined them on the main window or just in GM The call is wrapped in an anonymous function and passed into setTimeout

setTimeout( function() {
    mark2( "hello" )
}, 10 );                              //this alerts hello

Upvotes: 11

Brock Adams
Brock Adams

Reputation: 93473

Two issues:

  1. You can't set timers like this setTimeout("mark()",5000); in Greasemonkey. See GM pitfalls, Auto-eval Strings.

  2. There is currently a bug in Firefox 4. Alerts will fail inside timers. See "alert + setTimeout = failure". That's why Ander.by's answer does not work.

Upvotes: 1

mu is too short
mu is too short

Reputation: 434665

Yes, the Grease Monkey part might make a difference. Grease Monkey almost certainly wraps your JavaScript in a function to keep your JavaScript from conflicting with the page's JavaScript.

You're using the string form of setTimeout and there's no guarantee about what context the string will be executed in although it is probably in the global scope. Just because your function is visible where you execute setTimeout doesn't mean that your function will be visible when the string is evaled.

So, don't use the string form of setTimeout (ever), use Ander.by's approach or Walter Rumsby's anonymous function approach.

Upvotes: 0

Walter Rumsby
Walter Rumsby

Reputation: 7535

If the only place you need to call the mark function from is your timeout try:

setTimeout(function() {
    alert("This is a test box..");
}, 5000);

Upvotes: 1

Andrei
Andrei

Reputation: 4237

try to use thissetTimeout(mark,5000);

Upvotes: 5

Related Questions