Load jQuery only once on many-framed page - javascript

A key screen in my application involves a HTML page with several iframes performing various functions. All of these will need access to jQuery. In the interest of speeding up loading time, and reducing HTTP traffic (though I know caching could help with this), it would be good if the jQuery code itself were loaded only once. If my page is like so
<html>
<head>
<script src="jquery-1.5.js" type="text/javascript"></script>
</head>
<body>
<iframe src="other.html"></iframe>
<div id="foo"> ... stuff here ... </div>
</body>
</html>
Then inside other I can refer to parent.$('#foo') but that will refer to the parent's "foo" element, not the child's. Is there a way to use the parent's "instance" of jQuery on the child document or elements in it?

Have you tried:
var $ = window.parent.$;
$('#foo'); // parent's frame's #foo, is the same as "window.parent.$('#foo');"
and:
var $ = window.parent.$;
$('#foo', document); // this frame's #foo because the current document is given as context

Make sure each IFRAME references the exact same version of jquery. It should only get loaded once and be cached by the browser. IFRAMES don't have access to scripts of their parents.
You might also want to consider using a CDN for Jquery (such as Google's CDN) to improve performance.

We solved it with:
var window.jQuery = window.$ = function( selector, context ) {
return window.parent.jQuery(selector, context?context:window.document)
}

Related

getElementById unable to find the mistake in loop [duplicate]

Consider the script..
<html>
<head>
<script type="text/javascript">
document.write('TEST');
</script>
</head>
<body>
Some body content ...
</body>
</html>
This works fine and the word 'TEST' is added to the <body>
But when
<script type="text/javascript">
window.onload = function(){
document.write('TEST');
}
</script>
is used, then the body content is fully replaced by the word 'TEST' i.e, the old body contents are removed and ONLY the word 'TEST' is added.
This happens only when document.write is called within window.onload function
I tried this in chrome. Is there any mistake made by me ? any suggestions ?
document.write() is unstable if you use it after the document has finished being parsed and is closed. The behaviour is unpredictable cross-browser and you should not use it at all. Manipulate the DOM using innerHTML or createElement/createTextNode instead.
From the Mozilla documentation:
Writing to a document that has already loaded without calling document.open() will automatically perform a document.open call. Once you have finished writing, it is recommended to call document.close(), to tell the browser to finish loading the page. The text you write is parsed into the document's structure model. In the example above, the h1 element becomes a node in the document.
If the document.write() call is embedded directly in the HTML code, then it will not call document.open().
The equivalent DOM code would be:
window.onload = function(){
var tNode = document.createTextNode("TEST");
document.body.appendChild(tNode);
}
in the first case the word is not written in the body .. it is written in the head
the first one works because the document is still open for writting.. once it has completed (DOM loaded) the document is closed, and by attempting to write to it you replace it ..
When document is full loaded, any further call to document.write() will override document content. You must use document.close() before calling document.write() to avoid overwriting.
First create an element, for example a div, than add content to the div with window.onload event.
document.write('<div id="afterpostcontent"><\/div>');
window.onload = function()
{
document.getElementById('afterpostcontent').innerHTML = '<span>TEST<\/span>';
}
You can create an external JavaScript file with this content and just call it anywhere, for example:
<script src="afterpostcontentcode.js"></script>

Altering CreateElement method via Javascript doesn't work for iframes

I would like to globally redefine a createElement method, but unfortunately it only works in a main document, and is ignored in iframes. Let's take this example code:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script>
old_createElement = document.createElement;
document.createElement = function(el_type) {
new_el = old_createElement.call(this, el_type);
new_el.style.color="red";
return new_el;
};
</script>
</head>
<body bgcolor="white">
<iframe id="iframe1"></iframe>
<script type="text/javascript">
window.setTimeout(function(){
iframe_el = document.getElementById("iframe1").contentDocument.createElement("div");
iframe_el.innerHTML = 'inside iframe';
document.getElementById("iframe1").contentDocument.body.appendChild(iframe_el);
},50);
no_iframe_el=document.createElement('div');
no_iframe_el.innerHTML = 'outside of iframe';
document.body.appendChild(no_iframe_el);
</script>
</body>
</html>
When i open in in a browser, the element created in a main document has red color, as expected, but the one in the iframe is black.
The problem is that I only have control on the script contained in the HEAD section of the document. In other words, i don't know how many iframes there will be later on in the HTML source, or how they will be names, or if they are added via user's Javascript.
My question is: how can i change the method globally, so all elements created in iframes also use this new style?
Thanks a lot!
Each frame has it's own separate Javascript context. If you want to change that frame's context, you have to do it specifically for that frame.
In your specific example, each frame has its own document object so it should be no surprise that each document has its own .createElement property.
You cannot generically change things in a way that will affect all frames. And, in fact if it's a cross-origin frame, you can't change it at all.

Javascript: Best place to register event handlers

This question is so basic, I'm certain in must be a duplicate of something, even though I've looked for something similar.
My question is basically: Where is the best place to initially register event handlers for HTML elements?
The easiest way to register an event handler is obviously to just do it inline:
<div id = "mybutton" onclick = "doSomething()">Click me</div>
But this goes against the overwhelming march towards separation of logic and content in modern web development. So, in 2012, all logic/behavior is supposed to be done in pure Javascript code. That's great, and it leads to more maintainable code. But you still need some initial hook that hooks up your HTML elements with your Javascript code.
Usually, I just do something like:
<body onload = "registerAllEventHandlers()">
But... that's still "cheating", isn't it - because we're still using inline Javascript here. But what other options do we have? We can't do it in a <script> tag in the <head> section, because at that point we can't access the DOM since the page hasn't loaded yet:
<head>
<script type = "text/javascript">
var myButton = document.getElementById("mybutton"); // myButton is null!
</script>
</head>
Do we place a <script> tag at the bottom of the page or something? Like:
<html>
<body>
...
...
<script type = "text/javascript">
registerAllEventHandlers();
</script>
</body>
</html>
What is the best practice here?
You can use window.onload:
<script type = "text/javascript">
window.onload = registerAllEventHandlers;
</script>
Or if you use jquery:
$(registerAllEventHandlers);
Using onload works because it registers onload event immediately but fires it when DOM is ready.
I had a similar answer to this but was about JavaScript in general. But the idea is still the same - load scripts before closing the body.
Take advantage of libraries that abstract the window.onload and the DOM ready event. That way, you can load the scripts as soon as the DOM is ready.
Personally, I have no problems with adding onlclick="doSomething();" to elements. No logic, just a function call.
All logic is where it should be: in the function defined in the HEAD or a separate file.
Tell me what the difference is when you add href="somepage.html" or even href="somepage.html#someanchor" to an A tag.
You should register your event handlers as soon as the DOM is ready. Detecting this across all browsers hasn't always been easy, although with the notable exception of IE 8 (and earlier) most widely used browsers now support the DOMContentLoaded event (thanks to gengkev for pointing that out in the comments).
This is essentially equivalent to calling your registerAllEventHandlers function at the end of your body, but it has the advantage that you don't need to add any JavaScript to your HTML.
It is significantly better than using window.onload because that isn't executed until all of the page's assets (images, CSS etc.) have loaded.
If you're using one of the major JavaScript frameworks, then you can very easily detect when the DOM is ready, even in older versions of IE. With jQuery you would use the ready event:
jQuery(document).ready(function () {
// Your initialisation code here
});
Or the shorthand:
jQuery(function() { … });
With Prototype you would use the dom:loaded event:
document.observe("dom:loaded", function() {
// Your initialisation code here
});

Javascript onload in HTML

I want to ask a question about the Javascript’s onload.
I’m writing a JSP page with the code <%# include file ="body.jsp". The included body.jsp contains:
<table onload="function()">
This should load the javascript function, but it doesn't appear to have any effect on the page. Is onload only usable on the body tag?
Onload can only be used for <body>, <img>, <script>, <iframe> tags, because it tells you when an external resource (image, script, frame) or the whole page (body) has been loaded
Since HTML5 these can also fire a load event: <link>, <style>, <input type=image>, <object>
Support for these can still be a hit or miss though (e.g. older Android browsers)
Why not just include it via a <script tag>?
Inside your .jsp file
<script>
window.onload = function() {
alert("Hello!");
}
// or to execute some function
window.onload = myFunction; //notice no parenthesis
</script>
As the other guys already stated the onLoad event will not fire on a table. What you can do ist attaching the onLoad-handler to the body element (which will then fire, when the page is loaded) and manipulate the table by for example assigning an id to the table.
<body onload="function() { var table = document.getElementById("table-id"); ... }">
<table id="table-id"></table>
</body>
Are you using some javascript framework?
"onLoad" may be used on body- and frameset-tags.
To see some action you may use:
<body onload="function(){alert('This is an action!')}">
The easiest way i find is to use an external javascript file and jquery.
// Variables and functions you want to declare
var socket = io.connect();
// .....
// Function you want to run on load
$(function() {
$('#submit').click(function() {addUser();});
// ... any other functions you want to run on load
});
This is a code snippet from something that i was working on. The variable is declared before the code runs (It creates a web socket).
Then there is the jquery document selector ($) which runs on load and calls the init function to modify my html. I use it to call an anonymous function which runs right away.
You can throw a <script> tag right after your table with code. Once it gets to the script tag it would mean that the DOM for the table element above it has been loaded and can now be accessed in your script below it.
Note: The following below isn't applicable to the question but rather the other answers being given.
I recommend using the addEventListener function in javascript for adding the event. This makes sure that you are not overwriting or going to be overwritten by anyone else wanting to listen to the event.
Example
var iframe = document.getElementsByTagName('iframe')[0];
iframe.addEventListener('load', function(event){ console.log("iframe Loaded", event); })

What are the ways to minimize page wait from external javascript callouts?

What tricks can be used to stop javascript callouts to various online services from slowing down page loading?
The obvious solution is to do all the javascript calls at the bottom of the page, but some calls need to happen at the top and in the middle. Another idea that comes to mind is using iframes.
Have you ever had to untangle a site full of externally loading javascript that is so slow that it does not release apache and causes outages on high load? Any tips and tricks?
window onload is a good concept, but the better option is to use jQuery and put your code in a 'document ready' block. This has the same effect, but you don't have to worry about the onload function already having a subscriber.
http://docs.jquery.com/Core/jQuery#callback
$(function(){
// Document is ready
});
OR:
jQuery(function($) {
// Your code using failsafe $ alias here...
});
edit:
Use this pattern to call all your external services. Refactor your external script files to put their ajax calls to external services inside one of these document ready blocks instead of executing inline. Then the only load time will be the time it takes to actually download the script files.
edit2:
You can load scripts after the page has loaded or at any other dom event on the page using built in capability for jQuery.
http://docs.jquery.com/Ajax/jQuery.getScript
jQuery(function($) {
$.getScript("http://www.yourdomain.com/scripts/somescript1.js");
$.getScript("http://www.yourdomain.com/scripts/somescript2.js");
});
Not easy solution. In some cases it is possible to merge the external files into a single unit and compress it in order to minimize HTTP requests and data transfer. But with this approach you need to serve the new javascript file from your host, and that's not always possible.
I can't see iframes solving the problem... Could you please elaborate ?
See articles Serving JavaScript Fast and Faster AJAX Web Services through multiple subdomain calls for a few suggestions.
If you're using a third-party JavaScript framework/toolkit/library, it probably provides a function/method that allows you to execute code once the DOM has fully loaded. The Dojo Toolkit, for example, provides dojo.addOnLoad. Similarly, jQuery provides Events/ready (or its shorthand form, accessible by passing a function directly to the jQuery object).
If you're sticking with plain JavaScript, then the trick is to use the window.onload event handler. While this will ultimately accomplish the same thing, window.onload executes after the page--and everything on it, including images--is completely loaded, whereas the aforementioned libraries detect the first moment the DOM is ready, before images are loaded.
If you need access to the DOM from a script in the head, this would be the preferred alternative to adding scripts to the end of the document, as well.
For example (using window.onload):
<html>
<head>
<title>Test Page</title>
<script type="text/javascript">
window.onload = function () {
alert(document.getElementsByTagName("body")[0].className);
};
</script>
<style type="text/css">
.testClass { color: green; background-color: red; }
</style>
</head>
<body class="testClass">
<p>Test Content</p>
</body>
</html>
This would enable you to schedule a certain action to take place once the page has finished loading. To see this effect in action, compare the above script with the following, which blocks the page from loading until you dismiss the modal alert box:
<html>
<head>
<title>Test Page</title>
<script type="text/javascript">
alert("Are you seeing a blank page underneath this alert?");
</script>
<style type="text/css">
.testClass { color: green; background-color: red; }
</style>
</head>
<body class="testClass">
<p>Test Content</p>
</body>
</html>
If you've already defined window.onload, or if you're worried you might redefine it and break third party scripts, use this method to append to--rather than redefine--window.onload. (This is a slightly modified version of Simon Willison's addLoadEvent function.)
if (!window.addOnLoad)
{
window.addOnLoad = function (f) {
var o = window.onload;
window.onload = function () {
if (typeof o == "function") o();
f();
}
};
}
The script from the first example, modified to make use of this method:
window.addOnLoad(function () {
alert(document.getElementsByTagName("body")[0].className);
});
Modified to make use of Dojo:
dojo.addOnLoad(function () {
alert(document.getElementsByTagName("body")[0].className);
});
Modified to make use of jQuery:
$(function () {
alert(document.getElementsByTagName("body")[0].className);
});
So, now that you can execute code on page load, you're probably going to want to dynamically load external scripts. Just like the above section, most major frameworks/toolkits/libraries provide a method of doing this.
Or, you can roll your own:
if (!window.addScript)
{
window.addScript = function (src, callback) {
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.src = src;
script.type = "text/javascript";
head.appendChild(script);
if (typeof callback == "function") callback();
};
}
window.addOnLoad(function () {
window.addScript("example.js");
});
With Dojo (dojo.io.script.attach):
dojo.addOnLoad(function () {
dojo.require("dojo.io.script");
dojo.io.script.attach("exampleJsId", "example.js");
});
With jQuery (jQuery.getScript):
$(function () {
$.getScript("example.js");
});
If you don't need a particular script ad load time, you can load it later by adding another script element to your page at run time.

Categories

Resources