I am developing a game engine here:
http://synodins.com/apps/tank_fight
But now, for some reason, it doesn't run anymore.
I cannot initiate the Raphael module, when i run the site with mozilla web debugger, i get "Raphael is not defined".
But that doesn't make any sense because it's very clearly defined in the raphael.js module.
Also, occationally the game runs fine, like, every 20th time i try.
And there's no clear pattern to what makes it work.
I print out Hello world 1 before trying to initiate raphael, and hello world 2 after trying.
Can anybody see what the problem is?
The block of load_script calls loads the scripts asynchronously. This is why there appears to be no clear pattern.
There is no guarantee that raphael.js is loaded (and therefore, that Raphael is defined) by the time that the line:
var playing_area = Raphael(0,50,1600,1600);
is called.
You should wait until the whole document is ready before attempting to use variables defined in external scripts. Under normal circumstances, this is the onload event of the document. Various libraries like jquery also offer their own "ready" event, that you could tie to if you use them.
Is there any reason why you load the scripts in the way you do, rather than simply using markup, as below?
<script src="raphael.js"></script>
You are loading your scripts on demand - and this will speed up your initial page load. But right after that you try execute code in raphael.js - but loading of js files take some time and you have to be sure that they're loaded before you start calling functionality in them.
You may have a look at Modernizer.load() - this helps you to synchronize loading of resources and add callbacks when loading completes: http://www.modernizr.com/docs/#load
Have you tried moving 'raphael.js' to be included before anything else? It may be that Raphael is not defined at the point a script above it needs it.
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 see that Javascript code is normally in heading part of HTML code.
<head>
<script type="text/javascript" language="javascript" src="core.js"></script>
...
</head>
Is it OK to put the Javascript code in a body part of HTML code? I tested it, but it seems to work.
<body>
<script type="text/javascript" language="javascript" src="core.js"></script>
...
</body>
If so, why the examples of Javascript books put the javascript code in heading part?
If not, what's the difference between putting the javascript code in body/heading part?
Not only is it OK, it's actually better, since it lets the content come first.
If your viewers have a slow (eg, mobile) connection, it's better to send the actual content first, so that they can read it while the browser downloads the Javascript.
All the people saying it is better only applies if you are talking about at the bottom of the page (and that is an up for debate thing) from a code quality point of view, it is NOT ok to sprinkle script tags through your html. All references to javascript should be in a single place on the page, either the head (where they should be), or the very bottom (as a perf optimization)
Edit:
Basically, a web page is made up of 3 pieces; style (css), structure (html), and behavior (javascript). These pieces are all very distinct, so it makes sense to keep them as separate as possible. That way if you need to change some javascript, it is all in one place. If it is sprinkled through the file, it becomes much more difficult to find the code you are looking for, and that code basically becomes noise when you are just looking at structure.
It is the same arguments as why not sprinkle db access code all over your page. It has nothing to do with technical reasons, purely an architectural/design decision. Code that does different things should be kept separate for readability, maintainability, and by extension, refactorability (not sure if that last one is actually a word...)
You can do it, and people often do.
For example, people like to put their script tags just before the closing </body> to make web pages render quicker.
Also, if you do a script block after an element is created, you don't need to wait for DOM ready.
Be warned though, don't add, or remove an element from an unclosed ancestor in the markup tree (not including the script block's immediate parent element), or you will get the dreaded Operation Aborted error in IE.
Just something to add on:
I have preference of putting Javascript file right before </body>. My reasons being that:
Content can load and be shown first. If you load huge Javascript files first, which most are meaningless until the page is loaded, the user won't be able to see anything until the JS files are loaded.
Most Javascript code require to work with the UI can only run after the UI has been loaded. Placing the codes at the end of the html file reduces the need to use the onload event handler.
It is very bad habit to place Javascript snippets all over the HTML file. Placing all at the back of the HTML file allows you to manage your Javascript more efficiently.
It is legal according to the spec.
Most examples use them in the header as the headers come first and the browser will be able to parse the reference and download the JS files faster.
Additionally, these are links and are not part of the display, so traditionally, put in the header.
It is perfectly legal but there seem to be some differing opinions about it. Those who say to put all the javascript references in the head argue that the script is downloaded before the rest of the page become visible and dependent on it. So your user will not see an object on screen, attempt to interact with it and get an error because the javascript code is not yet loaded.
On the other hand, the argument goes that it takes longer to load all the script before the user sees the page and that can have a negative impact on perceived speed of your site.
JavaScripts inside body will be executed immediately while the page loads into the browser
Placing javascript at the end of the body will defer javascript load (ie: the page will render faster), but remember that any javascript function used for an event should be loaded before the event declaration, it is mainly because users may be able to fire an event before the page is completely loaded (so before the function is loaded)!
I used to put it in the head, then I've heard that it takes longer for the page to load so I started placing the scripts at the very bottom. However, I found out the most 'clean' way to do it is to place it in the head BUT you place the script inside a document.ready function. This way you have the best of both worlds. It is cleaner because it is in the head and it is not loaded before the content has been loaded, so there aren't any problems performance wise either.
With jQuery for instance, you can do it like this:
$(document).ready(function() {
alert('test');
});
The alert will only popup when the page has been fully loaded, even though the script is in the head.
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.
Why are JS scripts usually place in the header of a document? Is it required by standards, or is it just a convention with no particular reason?
See http://developer.yahoo.com/performance/rules.html#js_bottom
Although past practice has often been to place them in the header for the sake of centralizing scripts and styles (and the like), it is advisable now to place the scripts at the bottom to improve loading speed of the rest of the page.
To quote:
The problem caused by scripts is that they block parallel downloads. The HTTP/1.1 specification suggests that browsers download no more than two components in parallel per hostname. If you serve your images from multiple hostnames, you can get more than two downloads to occur in parallel. While a script is downloading, however, the browser won't start any other downloads, even on different hostnames.
In some situations it's not easy to move scripts to the bottom. If, for example, the script uses document.write to insert part of the page's content, it can't be moved lower in the page. There might also be scoping issues. In many cases, there are ways to workaround these situations.
An alternative suggestion that often comes up is to use deferred scripts. The DEFER attribute indicates that the script does not contain document.write, and is a clue to browsers that they can continue rendering. Unfortunately, Firefox doesn't support the DEFER attribute. In Internet Explorer, the script may be deferred, but not as much as desired. If a script can be deferred, it can also be moved to the bottom of the page. That will make your web pages load faster.
A <script src="url"></script> will
block the downloading of other page
components until the script has been
fetched, compiled, and executed. It is
better to call for the script as late
as possible, so that the loading of
images and other components will not
be delayed.
It depends on what the script is doing. If your code is wrapped in onLoad event then it doesn't matter since it will return almost immediately and not block otherwise you should put it where it fits because the placement does matter.
As for putting it at the end, it does give a little extra time for user to start looking at the page. Just ask yourself a question - does my site work without javascript? If it doesn't, then in my opinion it doesn't mater where you put it since onLoad code will only be executed when the DOM has been fully loaded (that includes binary content like images). If you can use it without javascript then put it at the end so that images can load faster.
Also note that most JS libraries use special code which works around the onLoad problem and uses custom event for this which gets fired once DOM has loaded and doesn't wait for binary data.
Now that I wrote all that, I got a question of my own. Does using say jQuery's
$(document).ready(function () {});
and putting the script tag at the end of page is the same as using onLoad event and putting it at the start?
It should be the same because browser would load all images before loading the script which is the last one in the list. If you know the answer leave a comment (I'm too lazy and it's too late to test it atm).
It's just a convention. It's usually recommended to put scripts at the end of the body so the page can display before loading them, which is always a plus. Also, document.body can't be used until the document is loaded or if you put the script in the body.
I've got a script executing on $(document).ready() that's supposed to vertically align block element in my layout. 90% of the time, it works without issue. However, for that extra 10% one of two things happens:
There's an obvious lag in the time it takes to do the centering, and the block elements jump into position. This could simply be performance related - as the page size is often large and there is a fair amount of javascript that is executing at once.
The centering will completely mess up, and the block element will either pushed down too far or not far enough. It appears as if it tried to calculate the height, but was getting improper measurements.
Is there any reason why executing a script on DOM-ready would not have all the correct CSS values injected into the DOM yet? (all CSS is in the <head> via a <link>).
Also, here's the script that's causing the issue (yes, it's been taken straight from here):
(function ($) {
// VERTICALLY ALIGN FUNCTION
$.fn.vAlign = function() {
return this.each(function(i) {
var ah = $(this).height();
var ph = $(this).parent().height();
var mh = (ph - ah) / 2;
$(this).css('margin-top', mh);
});
};
})(jQuery);
Thanks.
From the 1.3 release notes:
The ready() method no longer tries to make any guarantees about waiting for all stylesheets to be loaded. Instead all CSS files should be included before the scripts on the page. More Information
From the ready(fn) documentation:
Note: Please make sure that all stylesheets are included before your scripts (especially those that call the ready function). Doing so will make sure that all element properties are correctly defined before jQuery code begins executing. Failure to do this will cause sporadic problems, especially on WebKit-based browsers such as Safari.
Note that the above is not even about actually rendering the CSS, so you may still see the screen change when ready() kicks in. But it should save you from problems.
Actually, I find it a bit strange that just putting the CSS above the JS will solve all issues. The CSS is loaded asynchronously, so JS loading can start and finish while the CSS is still being downloaded. So if the above is a solution, then executing any JS code is then halted until all earlier requests have completed?
I did some testing, and indeed, sometimes JS is delayed until the CSS is loaded. I don't know why, because the waterfall shows that the JS has completed loading long before downloading the CSS has finished.
See JS Bin for some HTML and its results (this has a 10 second delay), and see webpagetest.org for its waterfall results. This uses some script from Steve Souders' cuzillion.com to mimic slow responses. In the waterfall, the reference to resource.cgi is the CSS. So, in Internet Explorer, the first external JS starts to load right after the CSS was requested (but that CSS will take another 10 seconds to finish). But the second <script> tag is not executed until the CSS has finished loading as well:
<link rel="stylesheet" type="text/css" href=".../a script that delays.cgi" />
<script type="text/javascript" src=".../jquery.min.js"></script>
<script type="text/javascript">
alert("start after the CSS has fully loaded");
$(document).ready(function() {
$("p").addClass("sleepcgi");
alert("ready");
});
</script>
Another test with a second external JS after getting jQuery, shows that the download of the second JS is not started until the CSS has loaded. Here, the first reference to resource.cgi is the CSS, the second the JS:
Moving the stylesheet below all JS indeed shows that the JS (including the ready function) runs much earlier, but even then the jQuery-applied class --which is yet unknown when the JS runs-- is used correctly in my quick tests in Safari and Firefox. But it makes sense that things like $(this).height() will yield wrong values at that time.
However, additional testing shows that it is not a generic rule that JS is halted until earlier defined CSS is loaded. There seems to be some combination with using external JS and CSS. I don't know how this works.
Last notes: as JS Bin includes Google Analytics in each script when running from the bare URL (like jsbin.com/aqeno, the test results are actually changed by JS Bin... It seems that the Output tab on the edit URL such as jsbin.com/aqeno/edit does not include the additional Google Analytics things, and surely yields different results, but that URL is hard to test using webpagetest.org. The reference to Stylesheets Block Downloads in Firefox and JavaScript Execution in IE as given by strager is a good start for a better understanding, but I got many questions left... Also note Steve Souders' IE8 Parallel Script Loading to make things even more complicated. (The waterfalls above are created using IE7.)
Maybe one should simply believe the release notes and documentation...
CSS/JavaScript/JQuery ordering doesn't work for me, but the following does:
$(window).load(function() { $('#abc')...} );
The DOM ready fires when all the DOM nodes are available. It has nothing to do with CSS. Try positioning the style before or try loading it differently.
To the best of my knowledge the ready event is fired when the DOM is loaded - which means that all the blocking requests (i.e. JS) have loaded and the DOM tree is completely graphed. The ready state in IE relies on a slower event trigger (document.readyState change vs DOMContentLoaded) than most other browsers so the timing is browser dependant also.
The existence of non-blocking requests (such as CSS and images) is completely asynchronous and unrelated to the ready state. If you are in a position where you require such resources you need to depend on the good old onload event.
According to HTML5, DOMContentLoaded is a plain DOM ready event without taking stylesheets into account. However, the HTML5 parsing algorithm require browsers to defer the execution of scripts until all previous stylesheets are loaded. (DOMContentLoaded and stylesheets)
In molily's tests (2010),
IE and Firefox blocked all subsequent script execution until stylesheets loaded
Webkit blocked subsequent execution only for external scripts (<script src>)
Opera did not block subsequent execution for any scripts
All modern browsers now support DOMContentLoaded (2017) so they may have standardized this behavior by now.