views:

1165

answers:

4

Hi All,

Thanks for reading.

I have several scripts that are built similar to the following:

scriptone.js

function FunctionOne(){

    // Do a bit of work...

    // Include a second javascript file, scripttwo.js
    // that contains a function called FunctionTwo.js
    var scrb = document.createElement('script');
    scrb.type = 'text/javascript';
    scrb.src = 'http://www.example.com/scripttwo.js?bunchofargs=varied';

    // Append it to the head.
    document.getElementsByTagName('head')[0].appendChild(scrb);

    // Can't run the second function directly, because it may not be loaded quite yet,
    // So use the Waiter function.
    Interval = setInterval("Waiter()", 10);

    // All done.
    return;

}

function Waiter(){
    if(window.FunctionTwo) {
     clearInterval(Interval);
     FunctionTwo();
    }
}

scripttwo.js

function FunctionTwo(){
    document.write('something based on calling page');
}

This works fine with FF and IE, but not with Opera or Chrome. In Chrome/Opera, everything seems to work ok in script one. However, nothing that should be happening in scripttwo.js actually happens. It's as if scripttwo.js didn't get included.

Any ideas why this doesn't work with Opera or Chrome?

Perhaps I'm using something that isn't compatible, or are there security features I am not aware of? All files are on the same domain.


Note Great replies - thanks so much!

FuncionOne is just a typo here, in the actual code, I use better function names, but I changed them here for readability. It may be the scope, though i agree with Joe White that it shouldn't be an issue. With JavaScript (one of my weak languages), who knows? FunctionOne is called from either the head or body of the HTML document.

I also like the idea of adding FuncTwo to the end of script two, to avoid the timer altogether. Cleaner, and so obvious once somebody points it out to you...

I will update after I work on this next.

Update Again:

Hi All,

I now have it working in FF, IE, and Chrome, but Opera seems to refuse to load any .js files at all now. I'm thinking this is just an Opera issue of some sort (http://stackoverflow.com/questions/1053676/opera-js-file-wont-load), and will proceed with the other three. Let you know how it turns out.

+1  A: 

Some questions/comments that might give you an answer:

  • What calls FuncionOne (notice your spelling)?

  • Timers are messy and don't always recurse (fire again unless stopped). I would refactor Waiter() to check Interval still exists and if not, create a recursive window.setInterval.

  • On that note, you might need to explicitly specify window.setInterval, not omitting the window.

  • Is the scope of Interval working? Your define it within a function. Traditional logic would say that clearInterval(Interval); in Waiter() would not have access... But JS is a little messy like that. Opera and Chrome might be a little less messy than you're hoping for. Merely defining it outside any function scope should fix that.

Oli
Interval isn't declared locally as a var; therefore it's implicitly Window.Interval (one of the things I hate about JavaScript). Scope shouldn't be an issue.
Joe White
Needless implicities should be the first things you target if you're sure your code should work but it doesn't run properly on some platforms. Each major browser runs its own implementation of Javascript so there's a lot of scope for things to fall through the gaps.
Oli
+2  A: 

You could probably just add FunctionTwo() to the end of scripttwo.js. Then it will run when it loads without the additional complexity of the interval.

SpliFF
+3  A: 

It works for me in Opera..

Instead of using the Waiter script, you could use an event:

scrb.onload = function() { FunctionTwo() }
scrb.onreadystatechange = function() { FunctionTwo() }

The second line is for Internet Explorer to work. A problem there is that Opera seems to hanle both these events, so FunctionTwo() would be executed twice. There are various ways to get around that. Browser detection, some global variable, etc.

Thorarin
+1  A: 

I think the problem is with the Interval scope. It is defined inside FunctionOne, but not in a global scope. So, I suspect that when it comes to execute Waiter, Opera and Chrome encounters that Interval is undefined and just silently drops out of FunctionTwo (maybe stops script?). FF and IE may just ignore this.

(BTW, what clearInterval should canonically do when it receives undefined parameter value?).

Thevs
Good question. http://www.w3schools.com/js/tryit.asp?filename=tryjs_setinterval Just tried it in Chrome and Firefox and it silently fails.
Nosredna