Where in the document to place javascript function definitions? - javascript

I have placed all my javascript calls inside jQuery.ready() to ensure the DOM is fully loaded before accessing them. But for function definitions (ones that I wrote myself), what's the best practice in placing them (before their corresponding called of course). At the beginning of <body>? Or at the end of <body>? Or inside jQuery.ready()? Or it simply doesn't matter? Thanks.

Do not place functions inside the ready() function.
You should declare them above the ready call and ideally all of your js is handled at the bottom of the html.

If you place your JavaScript in the head or top of the body, you will need to use jQuery ready IF they rely on some part of the DOM. As a shortcut, you can just pass your code to $, like so:
$(function(){
$("#domID").method();
});
However, you can forego this whole mess by putting your script at the bottom. The browser reads your HTML top to bottom. If the script that accesses domID, appears below the DOM element with id domID then it will work fine. So the above code snippet can be further simplified via:
$("domID").method();
As a note, this is not always the case. I have noticed you can not access canvas elements immediately. It may be safer to use $ or $.ready, then remove them as you become more comfortable with how the DOM and JavaScript are loaded.

Related

How can I extract the whole HTML of a page - before and after the DOM?

I'm trying to find a way to extract the HTML code of a web page using JavaScript in two editions:
Before the DOM / Before JS is applied
After the DOM / After JS is applied
All the JavaScript methods that I know just take it from the DOM element, like document.body or document.all... but non of them work specifically for before or after the DOM.
Added:
Just to focus the question further, this is not my page so I can't install any on the page, this is for any random web page.
Can you point me in the right direction? is there a specific method/command/process that is used in JavaScript and can do that? maybe I should stop the page load at specific point and take the code and then let it continue loading and take the code with the JS included?
Well, If you put a <script /> tag in the middle of your HTML your code will get executed before the continuation of the rest of your HTML.
also you can use
document.addEventListener("DOMContentLoaded", fn);
to call your function when the DOM is ready (it comes in the name of the event listener so sorry for over-explaination!)
Getting all the stuff is easy via the window object, can not imagine anything else you might need.
So if you want to do something before the DOM loads just put a <script /> tag at the top. if you want the dom to be ready use the DOMContentLoaded.
You can find great and complete documentation on this subject of script, async, defer on javascript.info. if there is anything that my explanation did not cover for you.

Adding a script to a DOM object

I want to add a script that applies to a DOM object of a certain type right after it is loaded/rendered. This type of object always comes together with the javascript script, and I want to put them together within some tag. Is it right to do it as below? If so, I suspect span is not the best tag to be used here because it may interact with the way the element inside will be displayed. What tag should I use?
<span>
<div>the dom object to be modified by the script</div>
<script>theJavascriptFunctionThatModifiesTheDomObject()</script>
</span>
I doubt this is the best way to load your script just after a particular element has been loaded by DOM due to these reasons:-
It makes your page load slower.
User will see your complete page in a discrete way.
Instead you should do this:-
Specify a selector to your element.
Include your single javascript code at the end of body.
Update DOM elements using that script.
EDIT:
Solution1: Append your JS at the end of body so that it has access to all the DOM elements.
Since you are injecting the element in DOM using ajax, you can define a success handler for XHR object which will modify your element in DOM.
Solution2: You can define a separate method in your JS and bind this method on some event. In your HTML markup define a data-event attribute and in your success handler append the element to DOM, extract the data-event using jquery data method and trigger that event.
Atleast it will keep you markup far away from scripting logic.
Some useful Links:
Best practices for speeding up your website - yahoo
Why we should load scripts at end - SO Link
The problem here is the script tag does not know where it is located in the DOM. It would be better to do something like add a class to the element[s] you want to alter. On DOM ready, you look up the element[s] and do your magic.
I would avoid this approach; scripts block the page loading
– so if you did this after several dom elements the page would run slow (or not at all if errors were found)
Try using jquery onready - example here : http://api.jquery.com/ready/
And scripts [usually] need to go on the bottom of the page to allow the page to load first
…there are exceptions to this rule such as the well known modernizer script library that needs to go first so it can evaluate the dom as it loads

$(function(){}) in body instead of head

$(function(){}) is the the same as jquery's $(document).ready so I am wondering if I can put it into body
instead of head ?
I only see the act of putting script at different section of the page as a matter of executing it at different time. It is true? Can I put script in a div in the middle of the page? Will it affect how DOM is loaded?
I only see the act of putting script at different section of the page as a matter of executing it at different time. It is true?
Yes, but the script you're talking about just makes a single function call (to ready). The callback will get called later, when the DOM is ready, either way.
Can I put script in a div in the middle of the page?
Yes. But again, if the script in question is just calling ready (directly, or via the shortcut), it doesn't much matter. I would discourage you from littering scripts all over your markup; best to try to keep the two largely separate.
Will it affect how DOM is loaded?
Only if you use document.write within the script (and even then, it doesn't affect how the DOM is loaded, but may affect the content of it).
If you can choose where the script tags go (e.g., you're not writing a JavaScript library or jQuery plug-in, your script is on a page you control), there's little if any reason to use ready. Instead, put your script tag at the end of the page, just before the closing </body> tag. References:
Google Closure engineers on when the DOM is ready
YUI Best Practices for Speeding Up your Website
The purpose of document.ready is to wait till the DOM is ready, if you put your scripts just before the body closing tag or just after the html that is being modified then you don't need document.ready although it should still work.
This will work but it is bad practice. If you can you should put your scripts at the end of your webpage rather than in the head. Unless of course you have something (like a document ready function) that you need to load first.

Dynamically Inserting <script> tags into HTML on Page Load

I'm trying to dynamically insert the Tweetmeme button using Javascript. I'm currently using jQuery throughout the site. Here's the script that I'm using. I basically want to cycle through all the blog entries with a class of journal-entry and append the following JavaScript to the end. This Javascript comes straight from tweetmeme.com. This doesn't work for me though and it has something to do with the code between append(). It doesn't like the second set of script tags.
<script type="text/javascript">
$(document).ready(function() {
$('.journal-entry').each(function(index) {
$(this).append('<script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"></script>');
});
});
</script>
Any help is appreciated.
Thanks.
Don't do this.
Inserting <script> HTML content into the DOM is unreliable: it works subtly differently in different browsers, and jQuery won't protect you from the differences.
In particularly, writing innerHTML never causes a <script> element's content to execute, but subsequently moving the <script> element from where it is to a new parent (which is part of jQuery's append process) may cause the script to execute, but not always (it depends on the browser).
In any case, it'll never work, because looking at button.js, it is calling document.write(). That function only makes sense to call at initial document parsing time; if you call it from an event afterwards, the call will simply replace the entire page content, destroying your existing page. A script that calls document.write() can only be run at document load time, from inside the execution path of a <script> element. You can't include the script in dynamically-created content at all, because it's not designed for it.
(If it makes you feel any better, it's barely designed at all; the button.js script is a badly broken load of old crap, including improper URL-escaping—using escape instead of the correct encodeURIComponent—and missing HTML-escaping. You may be better off well away from these total idiots.)
The closing </script> in the string in your append(...) call is closing the overall <script>
Try splitting it up into two strings. E.g:
$(this).append('<script type="text/javascript" src="http://tweetmeme.com/i/scripts/button.js"></'+'script>');

How can I have multiple document.observe(dom:loaded ...) functions inside one javascript file? (prototype)

Basically what I'm after is, following squashing all my JavaScript into one file (or a few files) how can I make a document.observe(dom:loaded({...})) function call for the right page?
So, say I have 5 pages in my website, and each one has a separate JS file. Inside each file is a load of page related functions, and a special function which sets up eventhandlers etc when the DOM has loaded. Obviously if all 5 pages include their own JS files then that's fine. But I want to compact all my JS into one page for versioning and efficiency reasons.
Therefore, in doing this, I would end up with 5 "dom:loaded" functions waiting to be setup. This won't do as the stuff inside these functions is page specific. So, my question is how can I do what I want to do without causing a whole bunch of DOM errors, and false eventhandler setup requests?
Ive considered namespaces and stuff like that but don't really know anything about it/them.
Btw, I'm using the Prototype lib. Oh, and my sites are considerably larger than 5 pages! :)
Thanks,
Lee
Some ideas:
inspect the dom to identify the page. For example, attach an attribute to the body element.
put a script tag in the page that sets a variable.
inspect the url.
when the load event fires, the event handler identifies the page and hands control off to the proper code.
I would give different IDs to the <body>s of the separate HTML files and test in the dom:loaded event the name of the <body> element using $$('body')[0].id.
I have opted to use a php regexp to capture the URI, then use this as the body ID. On my sites, where the page names are static, it means each page will have a unique ID.
I then include a JS file in the HEAD which contains a switch block inside which the appropriate code/functions are loaded. The switch block is inside the document.observe(dom:loaded...) function.
Works a treat!
Thank you again for your help.
I tend to always write my .js with no self activation (so much as possible)...
psuedo-code
namespace('mysite.section.init');
mysite.section.init.pageName = function(){
//stuff to run here...
};
in your home page, at the bottom, or via dom:loaded event simply run mysite.section.init.pageName();

Categories