While debugging, I see the message "Layout was forced before the page was fully loaded. If stylesheets are not yet loaded this may cause a flash of unstyled content." When I get this message, Firefox does not find my functions in
<script src='Game_Help.js' onload="alert('loaded')"></script>
If I remove <script>, the message goes away, but of course those functions are still not being found.
The strange thing is, I have a similar problem with Edge. Chrome works fine.
PS: I used the onload function to see if script was being loaded.
I can make a workaround using an iframe, but that seems strange.
So what is happening is that the alert itself is interrupting the loading of content, causing the warning. So to fix it (and keep the script in the head section), remove the onLoad event from your script tag, and add an event listener containing the alert to your external javascript file:
document.addEventListener("DOMContentLoaded", function(){ alert('loaded') });
This listener will wait until other content is loaded before it will run.
The other way to fix this is to move the script tag to the body (HTML loads top to bottom, so you are just letting everything else load up more or less until it gets to the script). If your content is fairly complex or there are multiple scripts using the event listener will be a more robust and specific solution.
Related
I am trying to hide my preloader with JavaScript once the DOM and at least the top content has been loaded. The problem is that my page has several iframes which can slow the process down a lot.
My understanding is that if I use jQuery's $(document).ready to hide the preloader, it will be hidden too soon. On the other hand, if I use $(window).load, the waiting time may be too long. So, is there a middle-way solution, - kind of like window.load but without waiting for iframes?
EDIT:
My page has stuff like Facebook Like button Google Translate and a few other scripts that work via iframes. These are not critical elements, and I would not like to wait for them to load fully.
On the other hand, CSS files like Bootstrap, jQuery, etc. are curcially important for the presentation, and therefore to show the page (hide preloader) w/o having these loaded first would be premature.
Thanks.
You could use $(document).ready to determine if a particular element is loaded before hiding your loader.
Or if you have partial views, to have a $(document).ready function in one of those pages js do the loader hide job.
Since you did not provide more info, these are closer to guesses than real solutions.
I think you're looking for document.onload, which will fire when the DOM tree is ready. I believe that it fires before iframes, which all get their own onload callback/event handler.
You can also try placing the script tag at the end of your html file without begin inside an onload or ready function. This will cause it to load the html content, then fire the Javascript.
EDIT
A thought just occurred to me, which may or may not be useful. You probably have an idea about when you want your script to execute. In whatever browser you are using, check the network tab of the development console. There may be some other element's onload function you want to wrap your code in. For example, if you have a background image you want to make sure loads before your code executes, you may want to use it's onload.
As Petre said, lack of info in the question makes answering difficult.
I'm trying to load a remote script with some function and the execute it inline in IE9.
However I encountered an error message that my function was undefined.
What it boils down to is that IE9 (and lower, it seems) executes the script in opposite the order I would expect. I made a simplified example, which still yields the same bug for me.
<script type="text/javascript" src="multibanner_rev04_tmp.js"></script>
<script type="text/javascript">alert('nr.2');</script>
The script has a longer path I edited out for readability, it only has an alert in it and nothing else.
the alert 'nr.2' executes before the one in multibanner_rev04_tmp.js in IE9
I've tried this on multiple computers with IE9, to make sure it wasn't the same problem as this: IE9 js load order and JQuery
Problem seems to be consistent. Also tried this on IE10, which does execute the alerts in the expected order.
I don't really get what's going on here, any ideas?
From your comment on the question:
The script is injected onto my page using yet antother script (through an ad-server), so that might be a problem worth checking out.
That's a completely different thing from what you actually have in your question. What you have in your question shows script tags in the markup; injecting a script with JavaScript is completely different.
There are two ways the ad script could be adding the script to the page:
Using document.write during the main page parsing to write out a script tag. You've said your page is XHTML strict. Using document.write to output markup to the page during the main parsing is invalid in XHTML, full stop. You cannot do it. If it works at all, the behavior is unspecified and you shouldn't rely on it.
If you want to use document.write during the main page parse, you have to stop using XHTML. At that point, the scripts will be evaluated in the order the parser sees them (regardless of how they got put in the parser's input stream, from the markup or via document.write).
By creating a script element (document.createElement('script')) and then appending that to the DOM. When you do this, the script is evaluated as soon as it's available. There is no order. It's just like using the async attribute in the markup (except that it's much more cross-browser reliable).
If that's how the script is added, you cannot rely on the order. If you control the script being added in this way, you could have that script check for whatever the other script provides and use setTimeout to defer its execution until that other thing shows up. If you don't, you'll have to delay the addition of the script element until you're ready for it.
(My first ever post to stackoverflow...)
Stating the obvious...the first script tag requires the browser to load a separate script file
whereas the second script tag has the javascript inline (in the HTML).
Assuming that you have "alert('nr.1');" at the top of your multibanner_rev04_tmp.js then it appears as though IE9 is executing the inline code first even though it
appears later in the HTML, which is incorrect behaviour according to this:
http://www.w3.org/TR/html5/scripting-1.html#script
If neither attribute [async or defer] is present, then the script is
fetched and executed immediately, before the user agent continues
parsing the page.
However, using IE10 with "IE9 standards" document mode set (I don't have IE9), I can't reproduce the behaviour you are seeing, which would sort of point towards a bug in IE9 itself or a specific version of IE9? I wonder what happens if you add a defer="defer" attribute to your second script tag ? (Just for diagnosis, because it's not strictly legal according to the standard without a "src" attribute.)
I'm using a src less iframe to develop a javascript widget to protect my css from the parent page.
It's perfectly working in chrome/safari. However in firefox I can see the content is added during few milliseconds and then the iframe becomes empty.
If I inspect html I see empty head and empty body, however if I inspect innerHtml through the console I can see that It has the right content...
I'm sorry I can't give you code as it's hard to pull out the relevant parts : I can tell you I access the iframe with jquery contents() and then find body or find head.
Any idea plz ?
I Managed to make an example : http://jsbin.com/arenat/2/edit#javascript,html,live
Just some code pull out to show the issue : working on chrome no in firefox (10.0.1). Hope it's enough.
When you add the frame to the DOM, it starts loading about:blank asynchronously. Then you modify the DOM in the iframe ... and then the asynchronous load completes and replaces the document you modified.
I suggest either using an onload handler on the iframe to do your manipulation after the about:blank has finished loading or using document.open() and document.close() to force cancellation of the async load.
It's working with a timeout :
http://jsbin.com/arenat/9/edit
I am inspecting some interesting behaviors of browser, I don't know it's in standard or not. If I put everythin inside <head></head>, the browser will only begin to render the page after all the resouces in head is retrieved.
So I am thinking that put as little as possible things into head is one of the important website optimization techniques, is it right? My question is:
If I put script/css in body or other parts of the html, how can I know that script has been loaded successfully so that I will not be calling a undefined function?
To answer shortly: You should really put the script tags at the very end of the <body> element. Style tags should be put in <head>, otherwise the document will have to be re-rendered every time a new stylesheet is loaded, so you really want them all to be loaded before the document starts rendering.
As for using javascript code that is not loaded yet. Of course you shouldn't bind any events or anything too early, and shouldn't have inline javascript in the page ideally. The solution can be to just use the window onload event to do your initialization, if you really must have inline code in the page.
Im experiencing strange behavior with Firefox and Dojo. I have a html page with these lines in the <head> section:
...
<script type="text/javascript" src="dojo.js" djconfig="parseOnLoad: true, locale: 'de'"></script>
<script type="text/javascript">
dojo.require("dojo.number");
</script>
...
Sometimes the page loads normally. But sometimes it won't. Firefox will fetch the whole html page but not render it. I see only a gray window.
After some experiments I figured out that the rendering problem has something to do with the load time of the html. Firefox starts evaluating the html page while loading it. If the page takes too long to load the above javascript will be executed BEFORE the html finishes loading.
If this happens I'll get the gray window. Advising Firefox to show me the source code of the page will display the correct complete html code. BUT: if I save the page to disk (File->Save Page As...) the html code will be truncated and the above part will look like this:
...
<script type="text/javascript" src="dojo.js" djconfig="parseOnLoad: true, locale: 'de'"></script>
<script type="text/javascript">
dojo.require("dojo.number");
</script></head><body></body></html>
This explains why I get to see a gray area. But why does this code appear there? I assume the require() method of Dojo does something "evil". But I can't figure out what. There is no write.document("</head><body></body></html>"); in the Dojo code. I checked for it.
The problem would be fixed, if I'd place the dojo.require("dojo.number"); statement in the window.load event:
<script type="text/javascript">
window.load=function() {
dojo.require("dojo.number");
}
</script>
But I'm curious why this happens. Is there a Javasctript function which forces Firefox to stop evaluating the page? Does Dojo do somethig "bad"? Can anyone explain this behavior to me?
EDIT: Dojo 1.3.1, no JS errors or warnings.
What does the rest of the page look like? What elements should be rendering that aren't? What other Javascript do you have?
What you have looks fine, but you will not be able to use methods in dojo.number or anything else loaded via dojo.require until after the page loads -- you must wait for window.onload to fire, or use the dojo.addOnLoad() method to trigger a callback. The latter is actually a bit quicker than onload.
dojo.require uses synch xhr to load which does block the browser, so if the load is unusually slow, you will notice a delay in the rendering of the page.
I think this is a rendering bug in Firefox that I've seen in a number of contexts where the one common factor is the amount of time the browser takes to load all the resources loaded in the of the page. The more scripts you have in the head that take a long time to request over the network or eval, the higher your chances are of running into this. Hitting the page with a warm cache notably reduces the possibility of running into the paint bug as well. Another way to mitigate it is to put the javascript at the end of the which is also a best practice since it doesn't block the browser from previewing markup immediately as it gets it.
Regarding the specifics of using dojo, common use cases include running things onload like creating and starting up widgets. If you have code in an onload handler that uses a dojo module like a widget, then stick the dojo.require statement inside the onload handler as well instead of before the onload handler. There's no point in suffering the performance penalty or blocking the initial UI rendering if you don't need it until later. Then build custom dojo layers to include the minimal core (possibly a custom base to make it even smaller) and the other 90% of what you need in a separate layer. Load the minimal core layer in the head (to get dojo.addOnLoad, etc) and then the other layer at the end of the body. If you live in a modular application framework where apps come and go in the page content area depending on the page you're on, each app should put the dojo.require statements for the respective dojo module it uses immediately before the module is actually referenced.
This won't work obviously if you need a module immediately in an inline script, but if that's the case then a custom dojo build will also help mitigate that case also.
I'm unaware of a reported issue with Mozilla, but I have also seen this much less often on other browsers some time ago.