Hi everyone.

I've run into another problem :(

I have 3 JS files I want to include in my page. The first one is defined statically in the html file. The other two are loaded into the DOM using the following function:

function loadJsFile(pathToFile){
	var headID = document.getElementsByTagName("head")[0];         
	var newScript = document.createElement('script');
	newScript.type = 'text/javascript';
	newScript.src = pathToFile;
	headID.appendChild(newScript);
}

I then use DOMContentLoaded or onload events to trigger my initiation function combining functions from the 3 files. This works perfectly in Opera, firefox and (I assume) Internet Explorer but doesn't work in Safari or Chrome. For those two browsers, I have resorted to using the onmouseover event.

I then tried and loaded the 3 files statically and that worked.

Any ideas?

btw: I'm a just a beginner to JS

Recommended Answers

All 15 Replies

Webkit browsers start executing javascript that is not tied to any event before the DOM finishes loading.

The exact cure depends on what is where, but the general idea is to put everything in onload= or readystatechange= event handlers. Sometimes moving everything to the end of the body [out of the <head>] will do it, but I'm guessing that may not be enough in this case.

Thanks for the reply.

I'm not sure how to use the readystatechange or the load them into the body. :S

I don't want to make a new thread on some other forum so I think I'll bump this one. :(
Hope someone is here to help me out ;)

First, putting the javascript at the end of the body

<script>
...
</script>
</body>

is trivial, if it happens to work.

Second, it isn't obvious why placing the script(s) 'statically' is not the complete solution (especially given that it works).

Finally, if for some reason you cannot give up on the event approach, Googling for
document.addEventListener("DOMContentLoaded"
will return links to the three 'experts' in this field (plus [indirectly] a link to a working example at
http://javascript.nwbox.com/ContentLoaded/
which goes far beyond the others in detail).

Note, however, that these pages were all written - literally - years ago and may thus have been overtaken by events - particularly the release of IE8.

FWIW, it appears to me that the most compact solution

(function (i) {
    var u = navigator.userAgent;
    var e = /*@cc_on!@*/false;
    var st = setTimeout;
    if (/webkit/i.test(u)) {
        st(function () {
            var dr = document.readyState;
            if (dr == "loaded" || dr == "complete") {
                i()
            } else {
                st(arguments.callee, 10);
            }
        }, 10);
    }
    else if ((/mozilla/i.test(u) && !/(compati)/.test(u)) || (/opera/i.test(u))) {
        document.addEventListener("DOMContentLoaded", i, false);
    } else if (e) {
        (

        function () {
            var t = document.createElement('doc:rdy');
            try {
                t.doScroll('left');
                i();
                t = null;
            } catch (e) {
                st(arguments.callee, 0);
            }
        })();
    } else {
        window.onload = i;
    }
})(init);

may actually be the best.

commented: As always, very helpful :) +2

Looks good but it seems too focussed on browser identification. As I can recall reading somewhere, browser identification should only be used when nothing else works.

This time I actually understand your script :) A week of coding really helps :D

This script seems to be a load better than mine. I gave up and came up with this

if (document.addEventListener){
	document.addEventListener('DOMContentLoaded', loadFiles, false);
	document.addEventListener('load',loadFiles,false);
}
else if (document.all && !window.opera){

	document.write('<script type="text/javascript" id="contentloadtag" defer="defer" src="javascript:void(0)"><\/script>');
	var contentloadtag=document.getElementById("contentloadtag");
	contentloadtag.onreadystatechange=function(){
		if (this.readyState=="complete"){
			loadFiles();
		}
	}
}
else if(document.attachEvent){
	document.attachEvent('onload',loadFiles);
}

then complimented it with the following. Note the s.setAttribute('onload','loadRespond()');

function loadJsFile(pathToFile){
	var e = document.getElementsByTagName('script')[0];
	var s = document.createElement('script');
	s.src = pathToFile;
	s.type = 'text/javascript';
	s.setAttribute('onload','loadRespond()');
	e.parentNode.insertBefore(s,e);
}

I finally got it working on all browsers:)although the functions that follow it do not support IE. :(
Hate IE now. It was never a problem with PHP but IE needs its own functions for everything. It's like another different language I have to learn.

Anyway, if you can point out any flaws or improvements that can be made, that'll be good. :)

BTW: +1 on your posts :D

it seems too focussed on browser identification. As I can recall reading somewhere, browser identification should only be used when nothing else works.

There is considerable debate on that point, especially because the alternative usually shown is feature testing, completely misapplied. In fact, your code has a perfect example of that. You are evidently assuming that this

if (document.all && !window.opera)

will be true only for IE; that is not correct.

Feature testing before trying to use the same feature is optimal. In all other cases, testing the user-agent is the proper way to go.

the functions that follow it do not support IE.

What functions? In what way?

There is considerable debate on that point, especially because the alternative usually shown is feature testing, completely misapplied. In fact, your code has a perfect example of that. You are evidently assuming that this

if (document.all && !window.opera)

will be true only for IE; that is not correct.

hmm I see. Lol the thing is at this point in time, I'm caring too much about IE so I just copy+pasted that in from somewhere. I think I'll try and replace it with your code. It seems pretty stable as long as the user doesn't disable user-agent identification or something.

What functions? In what way?

Functions like element.addEventListener and some other ones that I can't really find at the moment. The thing is I will leave the IE part out and just jquery and/or another set script or just adding additional browser specific code onto the original set.

IE FTL >=(

Functions like element.addEventListener

This

function attachListener(oElm, sTyp, fRef, bCapture)  // sTyp = 'name' [e.g., 'click']
{
	if (window.addEventListener)	{ // all others
		return oElm.addEventListener(sTyp, fRef, bCapture || false);
	} else if (window.attachEvent) { // IE
		return oElm.attachEvent('on' + sTyp, fFref);
	} else return false;
}

encapsulates the cross-browser issues and returns either false or the token needed to remove the listener. In this implementation the same function [the fRef parameter] is called on all platforms, so it must be cross-browser compatible [duh!].

Wow thanks :)

BTW: Line 6 I think should be return oElm.attachEvent('on' + sTyp, fRef); I guess this thread is solved then.

Thank you for all your help.

Arrg hopefully this is the final problem.

IE doesn't respond to addEvent(document.getElementById(id),'load',loadRespond) or s.setAttribute('onload','loadRespond')

function addEvent(oElm, sTyp, fRef, bCapture) { // sTyp = 'name' [e.g., 'click']
	if (window.addEventListener) { // all others
		return oElm.addEventListener(sTyp, fRef, bCapture || false);
	} else if (window.attachEvent) { // IE
		return oElm.attachEvent('on' + sTyp, fRef);
	} else return false;
}

function loadJsFile(pathToFile){
	var e = document.getElementsByTagName('script')[0];
	var s = document.createElement('script');
	var id = 'js' + loadJsId;
	s.src = pathToFile;
	s.type = 'text/javascript';
	s.id = id;
	e.parentNode.insertBefore(s,e);
	addEvent(document.getElementById(id),'load',loadRespond);
	loadJsId++;
}

LOL. Good catch on the typo. That will teach me not to clean up the variable names after testing - or at least to test again :(


IE doesn't respond to addEvent(document.getElementById(id),'load',loadRespond) or s.setAttribute('onload','loadRespond')

What do you mean by "doesn't respond"? Is the attribute not being set? Is the event not being added? Or is the function not being called?

To ensure that an event handler receives the onload event for an object, the script object that defines the event handler must appear [or at least be processed by the browser] before that object. Note: watch out for 'defer'; its affect (where it has any) varies by browser and depends in complex ways on the location(s) of the script object(s).

No, I didn't use defer because when I was playing around with it, Chrome just ignored it, Firefox used it and Opera didn't need it.

What do you mean by "doesn't respond"?

I know that the event is attached. At least, it returns true when I use attachEvent() and the DOM viewers don't show these event listeners. ( addEventListener() doesn't have any return values unfortunately.)

*10 Day Old Bump* (I'll delete this post)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.