Wednesday, December 23, 2009

Using different JQuery versions in the same page

Suppose your web page in the CMS is already using one version of jquery and you want to add a new HTML element with a javascript library that needs a more recent version of jquery.

You may think to use the google api like:

<script>
google.load("jquery", "1.3.2");
</script>



and then use the noConflict option like:




<script>
function OnLoad(){
jq13 = jQuery.noConflict(true);
}

google.load("jquery", "1.3.2");
google.setOnLoadCallback(OnLoad);
</script>



Unfortunately this will not work correctly in IE…so you may want to use the technique to dynamically load a javascript (see http://themnd.blogspot.com/2009/12/dynamically-load-javascript-on-webpage.html)






<script>
function OnLoad(){
jq13 = jQuery.noConflict(true);
}

function loadJQuery() {
loadJS('http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js', function() {
OnLoad();
});
}

jQuery(document).ready(function() {
setTimeout(function() {
loadJQuery();
}, 2000);
});
</script>



at this point you can load the needed library in the OnLoad function before setting the noConflict option. Please note that we are still using the google cdn to fetch the jquery library. The OnLoad function would be something like:




function OnLoad(){
loadJS(plugin_url, function() {
jq13 = jQuery.noConflict(true);
// now you can call the plugin methods here:
jq13.XXXX()
});
}

Dynamically load javascript on a webpage

When you work with a CMS sometimes you may need to dynamically add a javascript library on the fly.

The easiest thing to do is:

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



But what if you want to be notified when the javascript has been loaded? You can add the onload parameter:




newScript.onload = function(){
func();
};



but you will find out that this will not work in IE, so what you really need to use is:




function loadJS(url, func) {
var headID = document.getElementsByTagName("head")[0];
var newScript = document.createElement('script');
newScript.type = 'text/javascript';
if (newScript.readyState) { //IE
newScript.onreadystatechange = function() {
if (newScript.readyState == "loaded" || newScript.readyState == "complete") {
newScript.onreadystatechange = null;
func();
}
};
} else { //Others
newScript.onload = function(){
func();
};
}
newScript.src = url;
headID.appendChild(newScript);
}



We will rely on the onreadystatechange event that IE will fire, unfortunately that event is, in reality, the progress of the loading and sometimes it reach the “complete” state, sometimes only the “loaded” state, so if we really want to be sure that our callback will be called we have to get the first one and then cancel the event.



You can learn more at: http://www.nczonline.net/blog/2009/06/23/loading-javascript-without-blocking/



In a similar way you can also dynamically load CSS:




function loadCss(url) {
var headID = document.getElementsByTagName("head")[0];
var cssNode = document.createElement('link');
cssNode.type = 'text/css';
cssNode.rel = 'stylesheet';
cssNode.href = url;
cssNode.media = 'screen';
headID.appendChild(cssNode);
}