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');
}
}
Related
You might be familiar with the good old Jquery load fallback:
<script>window.jQuery || document.write('<script src="https://example.com/jquery.js"></script>')</script>
But I read here and there: don’t use document.write, is bad for your health, it does not work on Chrome (It’s working for me, Chrome 78).
So I’m trying to replace it, but I’m not able to find a solution that will load synchronously the new js file, before DOM loaded is triggered.
And what ends happening with a DOM manipulation alternative is that the browser consideres the DOM is loaded and all $(document).ready() fail with “$ is not defined”.
function Jqfallback() {
var j = document.createElement('script');
j.src = 'https://example.com/jquery.js';
document.getElementsByTagName('head')[0].appendChild(j);
}
(window.jQuery || Jqfallback() );
No matter where I put this script, or the new JS file, which in this case ('head')[0] is already before all other JS which are in the body, it loads it “asyncronically”.
Is there another option or I continue rocking document.write() in late 2019?
It takes a bit of time to load and parse JQuery. So use a (small) timeout after appending the script.
This snippet wraps conditional loading in a immediately executed anonymous function:
(myScripting => {
if (!window.$) {
let j = document.createElement('script');
j.src = '//code.jquery.com/jquery-3.4.1.slim.min.js';
document.querySelector('head').appendChild(j);
setTimeout( myScripting, 200 );
} else {
myScripting();
}
})(JqIsLoadedSoMyScriptingCanStart);
// put your main scripting in here
function JqIsLoadedSoMyScriptingCanStart() {
// extra check
if (!window.$) {
alert("Sorry, JQuery is not loaded, can't continue");
return;
}
console.log("JQuery in place?");
console.log($("head script")[1]);
}
<script src="cantLoadThis"></script>
Place the code that uses jQuery in the onload() function.
var jQuery1 = document.createElement('script');
jQuery1.src = "https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js";
jQuery1.onload = function () {
var $ = window.jQuery;
$.when(
$.getScript("https://someOtherScript.js"), //if you need
$.Deferred(function (deferred) {
$(deferred.resolve);
})
).done(function () {
console.log("all scripts loaded!!");
doNextTask(); //some other code which uses jQuery
});
};
Append jQuery to your document in onreadystatechange
document.onreadystatechange = function () {
if (document.readyState == "complete") {
// document is ready.
document.head.appendChild(jQuery1);
}
}
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']);
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.
I have reference to bunch of javascript file on my page which are used by different functions calls.
When I load the page, first all external JS files get loaded.
Is there anyway so that they get called only when function call occurs for that .js file?
You can add your conditions to this method, which allows you to dynamically add an external javascript file:
function loadScript(url, callback){
var script = document.createElement("script")
script.type = "text/javascript";
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);
}
By using JQuery
$.getScript("//platform.twitter.com/widgets.js")
No simple way for get JS fyle for function "on-fly". Also, for load file for function system need some time. May be good solution will using minification for JS-files?
You may try some as this.
loadExternalScriptFile = function(filename, callback) {
var fileref = document.createElement("script");
if (fileref){
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", filename);
fileref.onload = callback;
if (typeof fileref != "undefined")
document.getElementsByTagName("head")[0].appendChild(fileref);
}
}
var functionMap = {
'function1': 'js/f1.js',
'function2': 'js/f1.js',
'function3': 'js/f3.js'
};
function checkFunction(functionName, callback) {
if (typeof window[functionName] !== 'function') {
loadExternalScriptFile(functionMap[functionName], callback);
return;
}
callback();
return;
}
//Using
checkFunction('function1', function(){
function1(params);
});
But i think loading all in minification version and single file is better.
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.