Can script determine if window.onload has already fired?

D

David Mark

Indeed.

The lower signal/noise ration in here and the fewer posts is an
indicator as well.

Yes, it is very noisy in the jQuery group as few seem to have a clue
what they are discussing. ;) How is that a plus?
The jQuery group is being moved away from Groups because of
unmanageable spam. The number of readers may be reflected by this.

Yes, some of them may be spammers that got through rather than
readers. So you adjust the totals downward to compensate.
Or perhaps jQuery is becoming so well known and documented that not as
many people need help with it. How do you like them apples? :)

You know that's not true (at least if you have ever read the code).
Virtually every jQuery example in print or online uses the attr
method. How do you like that apple?

http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/e106af2d970d9b29#

It's rotten.
Or perhaps jQuery popularity is fading. If that's the case, so be it.

Yes, IE8's arrival coincides almost exactly with the nosedive trend.
Who could have seen that coming? :)
Perhaps it will be replaced by something different as the most popular
scripting library. Doesn't matter to me.

Obviously it will be "replaced". Science doesn't have any pity on
lazy, destructive code monkeys. And neither does business, but it
takes a while for ideas to percolate to that level.
 
D

David Mark

For example, something like GreaseMonkey. Or any tool which injects
scripts. Or perhaps a bookmarklet. Use your imagination, there are a
number of cases where a script under your control is injected into a
document and you have no control over the source document or when/how
your code gets inserted.

And, as mentioned, there is no magic property to determine if the
document has loaded. End of story for those examples.
The ajax/eval method was just an example.

Yeah, that's the one you came up with, so that's the one I responded
to.
 
G

Garrett Smith

Matt said:
There is a discussion going on in the jquery-dev mailing list that
piqued my curiosity. I'm interested to know if the smart people here
have a good answer.

Is there a cross-browser way, in script, to determine if window.onload
has already fired?

If a script is lazy loaded and needs the DOM to be ready, it can
attach to the window's load event. But if that has already fired, then
the script's code will never run. Alternatively, it can just fire its
code inline, but the DOM may not be ready.

Thoughts?
A follow-up to my previous message in this thread.

Solution:
The loaded script must not listen to any window load or readystatechange
events and must not call document.write (no jQuery.ready).

A Loader adds a load callback to a script element, then appends that
script, triggering the browser to load the script. When the script's
onload fires, the callback calls callback function.

Decoupling the loaded scripts from the loader avoids the tight coupling
and allows flexibility in loading. The module may provide an init()
method, so that the module can be re-inited if/when document innerHTML
changes.

In contrast, if the callbacks get attached in a hidden-in-module-scope
onload, they fire only on load. This is a problem when innerHTML
changes, and in your case where the onload may have already fired.

A dynamically loaded script must be designed in a way that it can be
loaded at any time without problems. It must not call document.write,
and must not listen for any load or readystatechange events.

Does this make sense?
 
J

Jorge

(...)
A Loader adds a load callback to a script element, then appends that
script, triggering the browser to load the script. When the script's
onload fires, the callback calls callback function.

IIRC, I've seen a couple of strange things happen when doing so. In
some browser(s) the onload may not even fire for <script>s. And in
some browsers I've seen both the <script>'s source being parsed/run
synchronously and the onload event being handled synchronously too
(when the <script> was cached and got fetched immediatly, on-the fly,
from the cache). Is it me, is it too much coke, or has somebody else
seen any of these too ?
 
D

David Mark

A follow-up to my previous message in this thread.

Solution:
The loaded script must not listen to any window load or readystatechange
events and must not call document.write (no jQuery.ready).

A Loader adds a load callback to a script element, then appends that
script, triggering the browser to load the script. When the script's
onload fires, the callback calls callback function.

I know you don't mean the load event of the SCRIPT element. That's
something to avoid, even in fantasy designs. ;)

"Jorge" actually got one right. I can't believe I'm saying this, but
have a look at his response.
 
G

Garrett Smith

Jorge said:
IIRC, I've seen a couple of strange things happen when doing so. In
some browser(s) the onload may not even fire for <script>s. And in
some browsers I've seen both the <script>'s source being parsed/run
synchronously and the onload event being handled synchronously too
(when the <script> was cached and got fetched immediatly, on-the fly,
from the cache). Is it me, is it too much coke, or has somebody else
seen any of these too ?

OK, you've got me. All the food got me a little euphoric yesterday. I
Wrote "Solution" when I should have written: "Untested solution".

Regarding the timing problems you mention with onload, I've not seen those.

Then again, I've not testing dynamic script injection much. For
requesting remote data, I have always used XHR or iframe. Those work
fine when used sparingly with small amounts of data.

Using dynamic script injection, the loader would listen for script's
onreadystatechange and check the readyState:

function loaderWrappedCallback() {
var readyState = script.readyState;
// TODO: Timeout events.
if(!readyState || "complete" === readyState) {
callback();
}
// TODO: Error handler.
}
}

Further testing is warranted before such experimental technique can be a
recommended solution.
 
D

David Mark

OK, you've got me. All the food got me a little euphoric yesterday. I
Wrote "Solution" when I should have written: "Untested solution".

Regarding the timing problems you mention with onload, I've not seen those.

Then again, I've not testing dynamic script injection much. For
requesting remote data, I have always used XHR or iframe. Those work
fine when used sparingly with small amounts of data.

Using dynamic script injection, the loader would listen for script's
onreadystatechange and check the readyState:

function loaderWrappedCallback() {
   var readyState = script.readyState;
// TODO: Timeout events.
   if(!readyState || "complete" === readyState) {
        callback();
     }
// TODO: Error handler.
   }

}

That's not a cross-browser solution either.
Further testing is warranted before such experimental technique can be a
recommended solution.

Solution for what? Knowing exactly when any random script has
finished loading? That's a fantasy aspiration. And I've seen people
trying to do similar things in projects where they actually have
control over the loaded scripts (or define the standards for them).

The only sane solution is to call the callback from the loaded
script. I know that doesn't fit the proposed fantasy design, but I
think it bears repeating at this point.
 
R

Richard Maher

Hi David,
Solution for what?
I am also not sure what problem the proposed solution solves. I thought the
OP wanted to delay till onload fired unless onload has fired in which case
run now.
Knowing exactly when any random script has
finished loading? That's a fantasy aspiration.
Based on available evidence I have to disagree. Depending of course on what
exactly you mean by "exactly" :)

As well as the cross-browser issues I'd include that ONERROR as well or you
might find your CALLBACK being a tad unreliable, but then you didn't like
"onerror" either.

BTW. Is the thrust of the requirements spec for this question the fact that
various "libraries" have become so bloated and convoluted that they can no
longer be feasibly loaded at "onload" time? So when some one says, for
example, "jQuery's footprint is 120KB" then that's just the bootstarp code
and oodles more will be lazily-loaded?

Cheers Richard Maher


OK, you've got me. All the food got me a little euphoric yesterday. I
Wrote "Solution" when I should have written: "Untested solution".

Regarding the timing problems you mention with onload, I've not seen those.

Then again, I've not testing dynamic script injection much. For
requesting remote data, I have always used XHR or iframe. Those work
fine when used sparingly with small amounts of data.

Using dynamic script injection, the loader would listen for script's
onreadystatechange and check the readyState:

function loaderWrappedCallback() {
var readyState = script.readyState;
// TODO: Timeout events.
if(!readyState || "complete" === readyState) {
callback();
}
// TODO: Error handler.
}

}

That's not a cross-browser solution either.
Further testing is warranted before such experimental technique can be a
recommended solution.

Solution for what? Knowing exactly when any random script has
finished loading? That's a fantasy aspiration. And I've seen people
trying to do similar things in projects where they actually have
control over the loaded scripts (or define the standards for them).

The only sane solution is to call the callback from the loaded
script. I know that doesn't fit the proposed fantasy design, but I
think it bears repeating at this point.
 
D

David Mark

Hi David,


I am also not sure what problem the proposed solution solves. I thought the
OP wanted to delay till onload fired unless onload has fired in which case
run now.


Based on available evidence I have to disagree. Depending of course on what
exactly you mean by "exactly" :)

What evidence is that?
As well as the cross-browser issues I'd include that ONERROR as well or you
might find your CALLBACK being a tad unreliable, but then you didn't like
"onerror" either.

If a script is a 404 or has a syntax error or whatever, the document
that included it better be equipped to do without it. And it
shouldn't need any sort of callback to tell it a script failed to
load.
BTW. Is the thrust of the requirements spec for this question the fact that
various "libraries" have become so bloated and convoluted that they can no
longer be feasibly loaded at "onload" time? So when some one says, for
example, "jQuery's footprint is 120KB" then that's just the bootstarp code
and oodles more will be lazily-loaded?

God only knows what jQuery developers are thinking. The base script
is too large and slow for mobile use (and full of extraneous garbage
that nobody needs). It makes life "simpler" by adding tons of
complexity and apps smaller by adding lots of unneeded script. Lazy
loading on top of it would be slower than including the scripts
normally. And they don't know how to do feature testing yet anyway,
so how would they decide what to lazy load. ;)
 
R

Richard Maher

David Mark said:
What evidence is that?

Anecdotal++ With all browsers tested to date (Chrome, FF, and Safari) the
onload or onerror combo fires every time. With IE 7,8 the readystate value
may be a source of contention but the event(s) fire every time. Do you have
any evidence to the contrary?

Our cases deal only with <script> injection and specifically with JSON
Callbacks. We are accessing and Application (Service-Now) in our Software
Providers "cloud" and as the network/application response to The States can
be woeful we desperately needed local (but cross-domain) data and
business-rule access/validation. We also have an SSO product that can
substitute a login page for our scripts when the session times-out.

I submit to you (sorry "The Group" :) that we have no silent failures and
we can verify the completeness of the load of our scripts. So you maintain
that I am living in cloud cuckoo land?

Cheers Richard Maher
 
J

Jorge

(...)
Anecdotal++ With all browsers tested to date (Chrome, FF, and Safari) the
onload or onerror combo fires every time. With IE 7,8 the readystate value
may be a source of contention but the event(s) fire every time. Do you have
any evidence to the contrary? (...)

So, the injected <script> either arrives or not, if it does you get
onload and if it doesn't you get onerror ?
Because, the onerror handler catches only http errors, right ?
 
R

Richard Maher

So, the injected <script> either arrives or not, if it does you get
onload and if it doesn't you get onerror ?

Yes (but IE is readystatechaneg)
Because, the onerror handler catches only http errors, right ?

Yes. The callback must use whatever protocol/flag you like to indicate it
fired. The oneload,onerror,onreadstatechange tells the loading script when
it's safe to to check the flag. If Site-Minder has got in the way the onload
fires but no flag has been set.
--

Cheers Richard Maher
 
D

David Mark

Anecdotal++ With all browsers tested to date (Chrome, FF, and Safari) the
onload or onerror combo fires every time. With IE 7,8 the readystate value
may be a source of contention but the event(s) fire every time. Do you have
any evidence to the contrary?

Your hypothesis is what? All you've done is to test some version of
three browsers (and two of them are virtually identical). If you are
on a search for a failure, you are taking the long way around. Think
about what _not_ finding a failure in 3, 30 or 300 browsers means.
You have to have some basis for your interpretation of the evidence.
Usually that starts with specs and history going back further than the
browsers in front of you. Anecdotal evidence is not a starting
point. Conclusions drawn strictly from observation are pretty much
baseless in browser scripting.
Our cases deal only with <script> injection and specifically with JSON
Callbacks. We are accessing and Application (Service-Now) in our Software
Providers "cloud" and as the network/application response to The States can
be woeful we desperately needed local (but cross-domain) data and
business-rule access/validation. We also have an SSO product that can
substitute a login page for our scripts when the session times-out.
Okay.


I submit to you (sorry "The Group" :) that we have no silent failures and
we can verify the completeness of the load of our scripts.

See above. What happens when you discover a browser that fails
silently? And why should you design your app(s) to rely on such
things if even their present viability is uncertain?
So you maintain
that I am living in cloud cuckoo land?

I don't recall saying that. :)
 
D

David Mark

Yes (but IE is readystatechaneg)


Yes. The callback must use whatever protocol/flag you like to indicate it
fired. The oneload,onerror,onreadstatechange tells the loading script when
it's safe to to check the flag. If Site-Minder has got in the way the onload
fires but no flag has been set.

Another observation. :)
 
G

Garrett Smith

David said:
[...]

The only sane solution is to call the callback from the loaded
script.

jQuery already has that (though slightly more elaborate). The script
calls jQuery.ready. If the jQuery.isReady flag is true, then the
callback fires immediately. Otherwise, the callback is added to an Array.

if ( jQuery.isReady ) {
// Execute the function immediately
fn.call( document, jQuery );
} else {
// Otherwise, remember the function for later
// Add the function to the wait list
jQuery.readyList.push( fn );
}

A call to jQuery.ready after the had fired would call that function.
 
D

David Mark

David said:
Jorge wrote:
(...)
[...]

The only sane solution is to call the callback from the loaded
script.  

jQuery already has that (though slightly more elaborate). The script
calls jQuery.ready. If the jQuery.isReady flag is true, then the
callback fires immediately. Otherwise, the callback is added to an Array.

But the isReady flag is dubious as it relies on jQuery's mixed up
DOMContentLoaded simulation. It's all fruit of a poisonous tree.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top