Can script.readyState be trusted to detect the end of dynamic script loading? Can script.readyState be trusted to detect the end of dynamic script loading? javascript javascript

Can script.readyState be trusted to detect the end of dynamic script loading?


In Opera, the script.readyState property cannot be trusted. For example, the readyState "loaded" may be fired before the script runs in Opera 9.64.

I performed the same test in Opera 9.64 and Opera 10, with different results.

In Opera 9.64, the onreadystatechange handler gets fired twice, once before and once after the script runs. The readyState property is "loaded" in both cases, which means that this value cannot be trusted to detect the end of the script loading:

# Fri Dec 18 2009 17:54:43 GMT+0100# Opera/9.64 (Windows NT 5.1; U; en) Presto/2.1.1Test for script.readyState behavior startedAdded script with onreadystatechange handlerreadystatechange: loadedtest1.js: Starttest1.js: Start of closuretest1.js: End of closurereadystatechange: loaded

In Opera 10, the onreadystatechange handler still gets fired twice with the value "loaded", but both times after the script ran:

# Fri Dec 18 2009 18:09:58 GMT+0100# Opera/9.80 (Windows NT 5.1; U; en) Presto/2.2.15 Version/10.10Test for script.readyState behavior startedAdded script with onreadystatechange handlertest1.js: Starttest1.js: Start of closuretest1.js: End of closurereadystatechange: loadedreadystatechange: loaded

These different behaviors indicate that onreadystatechange is not a reliable way to detect the end of a script loading in Opera. Since Opera also supports the onload listener, this other mechanism should be used instead.

Based on the results of these tests, onreadystatechange should only be used to detect the end of script loading in Internet Explorer, and it should not be set in other browsers.


In Firefox, Safari and Chrome, the onreadystatechange handler nevers gets called.

I created a short test case, creating a dynamic script with only the onreadystatechange handler set:

<script type="text/javascript" language="javascript">bezen.log.info(new Date(),true);bezen.log.info(navigator.userAgent,true);// Activate logsbezen.log.on();bezen.log.info('Test for script.readyState behavior started');var script = document.createElement('script');script.src = 'test1.js';script.onreadystatechange = function(){  bezen.log.info('readystatechange: '+script.readyState);};document.body.appendChild(script);bezen.log.info('Added script with onreadystatechange handler');</script>

I performed the test on a local file in Firefox 2, Firefox 3, Firefox 3.5, Safari 3, Safari 4 and Chrome 3, and got similar results (here the logs recorded in FF 3.5):

Fri Dec 18 2009 17:53:58 GMT+0100Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6Test for script.readyState behavior startedAdded script with onreadystatechange handlertest1.js: Starttest1.js: Start of closuretest1.js: End of closure

The onreadystatechange never gets called. In these browsers, only the onload listener is useful to detect the end of a script loading, the onreadystatechange is not needed.


In Internet Explorer, the onreadystatechange handler fires as expected, after the end of the script.

I performed the same test in Internet Explorer 6, Internet Explorer 7 and Internet Explorer 8, with similar results in these three browsers (here the logs recorded in Internet Explorer 6):

Fri Dec 18 18:14:51 UTC+0100 2009Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)Test for script.readyState behavior startedAdded script with onreadystatechange handlertest1.js: Starttest1.js: Start of closuretest1.js: End of closurereadystatechange: complete

Here, with a test using a local file, the readyState is always "complete", and it was still the same after several page refresh.

However, as noted in this post by Nicholas C. Zakas, you may also observe "loaded" and "complete", or just "loaded", under different circumstances.