Dynamically loading CSS - javascript

I'm trying to create a page theme function for my site. I want to load the corresponding themes dynamically on the page using separate CSS files.
I'm using this code:
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("href", 'link.css')
document.getElementsByTagName("head")[0].appendChild(fileref)
Which works fine, but it doesn't return any info if the CSS file has loaded or not.
Is there a way to catch when the .css is loaded? Maybe by using ajax?

Internet Explorer will trigger an onReadyStateChange event when CSS file is loaded (or any other change in it's readyState).
Other browsers do not trigger any event, so you will have to manually check if the stylesheet has been loaded, which is easily possible by checking the document.styleSheets object at a fixed interval.
Example
window.onload = function (){
var filename = "link.css",sheet,i;
var fileref = document.createElement("link");
fileref.setAttribute("rel", "stylesheet");
fileref.setAttribute("type", "text/css");
fileref.setAttribute("href", filename);
readyfunc = function () {
alert("File Loaded");
}
timerfunc = function (){
for (i=0;i<document.styleSheets.length;i++){
sheet = document.styleSheets[i].href;
if(sheet !== null && sheet.substr(sheet.length-filename.length) == filename)
return readyfunc();
}
setTimeout(timerfunc,50);
}
if (document.all){ //Uses onreadystatechange for Internet Explorer
fileref.attachEvent('onreadystatechange',function() {
if(fileref.readyState == 'complete' || fileref.readyState == 'loaded')
readyfunc();
});
} else { //Checks if the stylesheet has been loaded every 50 ms for others
setTimeout(timerfunc,50);
}
document.getElementsByTagName("head")[0].appendChild(fileref);
}
It's ugly, but it works in all browsers.

Related

error loading javascript files dynamically

i am trying to lazy (dynamically) load javascript files in my webpage.
i have used this :
http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml
function loadjscssfile(filename, filetype){
if (filetype=="js"){ //if filename is a external JavaScript file
var fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript")
fileref.setAttribute("src", filename)
}
else if (filetype=="css"){ //if filename is an external CSS file
var fileref=document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("href", filename)
}
if (typeof fileref!="undefined")
document.getElementsByTagName("head")[0].appendChild(fileref)
}
loadjscssfile("myscript1.js", "js") //dynamically load and add this .js file
loadjscssfile("myscript2.js", "js") //dynamically load and add this .js file
loadjscssfile("myscript3.js", "js") //dynamically load and add this .js file
these 3 script are to be loaded in a sequence.
myscript3 is dependent on myscript2
and myscript2 is dependent on myscript1.
trying to load it in this way is behaving wierdly.
Looks like these are not loaded in the sequence intended and hence
undefined errors are thrown at times and at times no error are thrown.
Am i doing something wrong.
Updated :
I am using this code to load the files in the correct sequence
function loadjscssfile(filename, filetype) {
if (filetype == "js") { //if filename is a external JavaScript file
var fileref = document.createElement('script')
fileref.setAttribute("type", "text/javascript")
fileref.setAttribute("src", filename)
}
else if (filetype == "css") { //if filename is an external CSS file
var fileref = document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("href", filename)
}
return fileref;
}
function loadSync(files, types) {
if (typeof (files[0]) === 'undefined') return false;
var script = loadjscssfile(files[0], types[0]);
script.onload = function () {
files.shift();
types.shift();
loadSync(files, types);
}
if (typeof script != "undefined")
document.getElementsByTagName("head")[0].appendChild(script)
}
loadSync(['scripts/module3.base.js', 'scripts/module3.core.js', 'scripts/module3.init.js'], ['js', 'js', 'js']);
console.log('this should get printed when all the three files are loaded');
But the console output is :
this should get printed when all the three files are loaded
scripts/module3.base.js:9 base is initialised
scripts/module3.core.js:6 core is initialised
scripts/module3.init.js:3 app is initialsed
Looks like the first call to loadSync is itself an Asynchronous call
There are open source js which will ease your problem.
You can use LABJS or RequreJS plugins.
Script loaders like LABJS, RequireJS will improve the speed and quality of your code.
You can preserve order of loading your script like this in LABJS.
$LAB.setOptions({AlwaysPreserveOrder:true})
.script("script1.js")
.script("script2.js")
OR
$LAB
.script("script1.js").wait()
.script("script2.js")
script2.js will wait untill script1.js is loaded.
I guess this will solve your problem.
For HTML5 just use async attribute ( info at http://davidwalsh.name/html5-async )
Example of function for loading script with a optional callback option
function loadScript(url, callback) {
if (!callback) callback = function () {};
var script = document.createElement("script")
script.type = "text/javascript";
script.setAttribute("async", "true");
if (script.readyState){ //IE
script.onreadystatechange = function(){
if (script.readyState == "loaded" ||
script.readyState == "complete"){
script.onreadystatechange = null;
callback();
}
};
} else { //Others
script.onload = function(){
callback();
};
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}
For a mixed solution:
function loadjscssfile(url, type, callback) {
if (!type) {
type = "js";
}
var node;
if (type === "js") {
var node = document.createElement("script")
node.setAttribute("async", "true");
node.type = "text/javascript";
if (node.readyState){ //IE
node.onreadystatechange = function(){
if (node.readyState == "loaded" ||
node.readyState == "complete"){
node.onreadystatechange = null;
callback();
}
};
} else { //Others
node.onload = function(){
callback();
};
}
node.src = url;
} else if (type === "css") {
var node = document.createElement("link")
node.type = "text/css";
node.setAttribute("rel", "stylesheet");
node.setAttribute("async", "true");
if (node.readyState){ //IE
node.onreadystatechange = function(){
if (node.readyState == "loaded" ||
node.readyState == "complete"){
node.onreadystatechange = null;
callback();
}
};
} else { //Others
node.onload = function(){
callback();
};
}
node.href = url;
}
if (node) {
document.getElementsByTagName("head")[0].appendChild(node);
} else {
callback(new Error("File not found"));
}
}
Loading a list of files
function loadjscssfileList(arr_original, callback) {
var arr = [];
arr_original.forEach(function (v) {
arr.push(v);
});
var next = function () {
if (arr.length) {
var file = arr.shift();
loadjscssfile(file[0], file[1], function () {
next();
});
} else {
callback();
}
};
next();
};
// use without callback
loadjscssfileList([
["myscript.js","js"],
["style.css","css"],
["myscript2.js","js"]
]);
// use with callback
loadjscssfileList([
["myscript.js","js"],
["style.css","css"],
["myscript2.js","js"]
], function () {
alert("loaded")
});
you can load them synchronously.
function get_contents(file){
var xhr = new XMLHttpRequest();
xhr.open('get', file, false);
xhr.send();
return xhr.responseText;
}
function loadjscssfile(filename, filetype){
var content = get_contents(filename);
if (filetype=="js"){ //if filename is a external JavaScript file
var fileref=document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.innerHTML = content;
}
else if (filetype=="css"){ //if filename is an external CSS file
var fileref=document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.innerHTML = content;
}
if (typeof fileref!="undefined")
document.getElementsByTagName("head")[0].appendChild(fileref)
}
To load it externally:
there're 2 ways:
Callback as the another answer.
Or you can do this:
function loadjscssfile(filename, filetype){
if (filetype=="js"){ //if filename is a external JavaScript file
var fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript")
fileref.setAttribute("src", filename)
}
else if (filetype=="css"){ //if filename is an external CSS file
var fileref=document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("href", filename)
}
return fileref;
}
function loadSync(files,types){
if(files[0] === 'undefined')return false; //if there's no files to load
var script = loadjscssfile(files[0],types[0]); //load first file
script.onload = function(){//after the script is loaded delete them and continue;
files.shift();
types.shift();
loadSync(files,types);
}
if (typeof script !="undefined")
document.getElementsByTagName("head")[0].appendChild(script)
}
loadSync(["myscript1.js","myscript2.js","myscript3.js"],['js','js','js']);

Ajax content not loading in IE throws 'error on page - access is denied' error but works fine on server

I made a tool for my organization which loads html pages into one main html file(through AJAX) on choosing an option from a select list. Each selection loads a different html file.
Things looked good when I tested it from home. When I opened it through IE8 from office (no other browser is allowed - plain stupid) all hell broke loose. First it messed up the layout reason being the organization's intranet. I had to use,
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
This solved the layout problem still the Ajax won't load. Which is the very basic thing for this tool to work. I tried using Msxml2.XMLHTTP / Microsoft.XMLHTTP instead of XMLHttpRequest - it wouldn't work. Would someone be kind enough to help me with this? Here's the code:
<script type="text/javascript">
var loadedobjects = ""
var rootdomain = "http://" + window.location.hostname
function ajaxpage(url, containerid) {
var page_request = false
if (window.XMLHttpRequest) // if Mozilla, Safari etc
page_request = new XMLHttpRequest()
else if (window.ActiveXObject) { // if IE
try {
page_request = new ActiveXObject("Msxml2.XMLHTTP")
}
catch (e) {
try {
page_request = new ActiveXObject("Microsoft.XMLHTTP")
}
catch (e) {}
}
}
else
return false
page_request.onreadystatechange = function() {
loadpage(page_request, containerid)
}
page_request.open('GET', url, true)
page_request.send(null)
}
function loadpage(page_request, containerid) {
if (page_request.readyState == 4 &&
(page_request.status == 200 || window.location.href.indexOf("http") == -1))
document.getElementById(containerid).innerHTML=page_request.responseText
}
function loadobjs() {
if (!document.getElementById)
return
for (i = 0; i < arguments.length; i++) {
var file = arguments[i]
var fileref = ""
if (loadedobjects.indexOf(file) == -1) { // Check to see if this object has not already been added to page before proceeding
if (file.indexOf(".js") != -1) { // If object is a js file
fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", file);
}
else if (file.indexOf(".css") !=-1 ) { // If object is a css file
fileref=document.createElement("link")
fileref.setAttribute("rel", "stylesheet");
fileref.setAttribute("type", "text/css");
fileref.setAttribute("href", file);
}
}
if (fileref != "") {
document.getElementsByTagName("head").item(0).appendChild(fileref)
loadedobjects += file + " " // Remember this object as being already added to page
}
}
}
</script>

how to create a reusable javascript web-app from my HTML CSS and JS files

i have a working HTML file with CSS and JS files i want to create a web app with this.
i don't have any experience or idea how to create a webapp from what i have.
my code dosen't need any interaction with the server.
i have found this guide from this site
(function() {
// Localize jQuery variable
var jQuery;
/******** Load jQuery if not present *********/
if (window.jQuery === undefined || window.jQuery.fn.jquery !== '1.4.2') {
var script_tag = document.createElement('script');
script_tag.setAttribute("type","text/javascript");
script_tag.setAttribute("src",
"http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js");
if (script_tag.readyState) {
script_tag.onreadystatechange = function () { // For old versions of IE
if (this.readyState == 'complete' || this.readyState == 'loaded') {
scriptLoadHandler();
}
};
} else {
script_tag.onload = scriptLoadHandler;
}
// Try to find the head, otherwise default to the documentElement
(document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
} else {
// The jQuery version on the window is the one we want to use
jQuery = window.jQuery;
main();
}
/******** Called once jQuery has loaded ******/
function scriptLoadHandler() {
// Restore $ and window.jQuery to their previous values and store the
// new jQuery in our local jQuery variable
jQuery = window.jQuery.noConflict(true);
// Call our main function
main();
}
/******** Our main function ********/
function main() {
jQuery(document).ready(function($) {
/******* Load CSS *******/
var css_link = $("<link>", {
rel: "stylesheet",
type: "text/css",
href: "style.css"
});
css_link.appendTo('head');
/******* Load HTML *******/
var jsonp_url = "http://al.smeuh.org/cgi-bin/webwidget_tutorial.py?callback=?";
$.getJSON(jsonp_url, function(data) {
$('#example-widget-container').html("This data comes from another server: " + data.html);
});
});
}
})(); // We call our anonymous function immediately
1.) i understood till loading CSS but i did not get what the code is doing for loading a HTML file.
2.) is it possible to do a webapp with what i have and how..?
3.) i know css html js jq.......... is it important to know ajax or anything else for creating a web app.
thank you.
I'm not sure if I understand your question, but maybe if I try to describe what this script is doing, it will help you?
Basically, this script is (somewhat clumsily IMO) first loading jQuery, and then loading a stylesheet style.css and finally retrieving data from http://al.smeuh.org/cgi-bin/webwidget_tutorial.py?callback=?. It assumes that you have a document element with the id "example-widget-container", which is where it will inject the html received from the JSON call.
If you clarify what exactly you're asking, then maybe I or someone else can help you some more.

Loading content using AJAX, which has script tags in it

What i really want to do is, simulate all the functionalities of an Iframe in my windows 7 gadget, without the cross-domain restrictions.
So is it possible , that I load a full html page, with <html>, <body> and <script> tags, and load all this is a div/some dom, so that all the elements of the loaded html are rendered, executed as in an Iframe.
I'm pretty sure there does exist a library for the same, but help from guys here is very reliable, hence posting on this forum.
Thanks.
the easiest thing to do is, use the jquery.ajax load funciton , parse the data, get the script tags data in another var, put this into javascript eval function , somewehre on the page, and put the other data wherever that you need to new DOM to be inserted at.
I understand that you want to load an entire page inside an HTML element using Ajax, you can do it but is wrong. The right thing to do is load external scripts or styles.
<!doctype html>
<html>
<head>
<script>
(function () {
var _css;
Element.prototype.pullCssJs = function (folder) {
var _length = folder.length;
folder = folder[_length - 1] === "/" ? folder : folder + "/";
if (typeof _css === "undefined") {
// Same
var css = document.createElement ("link");
css.setAttribute ("href", folder + "css.css");
css.setAttribute ("rel", "stylesheet");
css.setAttribute ("type", "text/css");
document.getElementsByTagName("head")[0].appendChild (css);
_css = css;
}
else {
if (_css !== css) {
var head = document.getElementsByTagName("head")[0];
// Same
var css = document.createElement ("link");
css.setAttribute ("href", folder + "css.css");
css.setAttribute ("rel", "stylesheet");
css.setAttribute ("type", "text/css");
head.removeChild (_css);
head.appendChild (css);
_css = css;
}
}
var js = document.createElement ("script");
js.setAttribute ("src", folder + "js.js");
js.setAttribute ("type", "text/javascript");
element.appendChild (js);
}
})();
window.addEventListener ("load", function () {
document.body.addEventListener ("click", function (event) {
var target = event.target;
if (target.nodeName === "A") {
var con = new XMLHttpRequest ();
var href = target.href;
con.open ("GET", href, true);
con.send (null);
con.onreadystatechange = function () {
if (con.readyState === 4) {
if (con.status === 200) {
var element = document.getElementById ("element");
var folder = href.substr (0, href.lastIndexOf ("/"));
element.innerHTML = con.responseText;
element.pullCssJs (folder);
}
else {
alert ("Error");
}
}
}
event.preventDefault ();
}
}, false);
}, false);
</script>
<style>
#element {
border: 1px solid black;
margin: 20px;
padding: 20px;
}
</style>
<title></title>
</head>
<body>
Call folder1/index.htm <br />
Call folder2/index.htm <br />
Call folder3/index.htm
<div id = "element"></div>
</body>
</html>
Just put the style (css.css) and the script (js.js) in the same folder of the file you want to load and this code will do the trick.
You can download the following example:

Load jQuery, wait

I need to dynamically load jQuery and jQuery UI from a javascript, then check if it has loaded and do something afterwards.
function loadjscssfile(filename, filetype){
if (filetype=="js"){ //if filename is a external JavaScript file
var fileref=document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", filename);
}
else if (filetype=="css"){ //if filename is an external CSS file
var fileref=document.createElement("link");
fileref.setAttribute("rel", "stylesheet");
fileref.setAttribute("type", "text/css");
fileref.setAttribute("href", filename);
}
if (typeof fileref!="undefined")
document.getElementsByTagName("head")[0].appendChild(fileref);
}
loadjscssfile("http://localhost/js/jquery-1.3.2.min.js", "js");
loadjscssfile("http://localhost/js/jquery-ui-1.7.2.custom.min.js", "js");
I have done some research and found that I need to either use a callback or a settimeout. Trouble is I'm really new in javascript and it's really giving me a hard time. Can anyone set me in the right direction please?
I've never had to do this myself, but presumably you could just use a repeating timeout to check for presence of the needed objects:
function jqueryLoaded() {
//do stuff
}
function checkJquery() {
if (window.jQuery && jQuery.ui) {
jqueryLoaded();
} else {
window.setTimeout(checkJquery, 100);
}
}
checkJquery();
I'm pretty sure that the window.onload() function should trigger when all scripts are loaded. And you don't need to bind stuff to the 'ready' event in jQuery.
loadjscssfile("http://localhost/js/jquery-1.3.2.min.js", "js");
loadjscssfile("http://localhost/js/jquery-ui-1.7.2.custom.min.js", "js");
window.onload = function() {
if(window.jQuery && jQuery.ui) {
alert('loaded');
}
}

Categories

Resources