can u fix my js dynamic loading doesnt work? - javascript

i want to add a js script in another js page but its does'nt work i don't know i want to add jquery but still undifiend :
plugins.js :
var jquery = document.createElement("script");
jquery.type = "text/javascript";
jquery.src = "assets/vendor/js/jquery.min.js";
document.body.appendChild(jquery);
index.html :
<body>
<script src="./assets/js/plugins.js"></script>
<script src="./assets/js/main.js"></script>
</body>
</html>
and the bug :
Uncaught ReferenceError: $ is not defined
at main.js:1

If the ask is to load the scripts dynamically, you can load the jquery library via the plugins.js followed by the main.js file this way. This will work and work as intended.
<body>
<script>
(function () {
function loadScript(url, afterLoad) {
var script = document.createElement("script")
script.type = "text/javascript";
script.onload = function () {
afterLoad();
};
script.src = url;
document.getElementsByTagName("body")[0].appendChild(script);
}
loadScript('./assets/js/plugins.js', function () {
console.log('jquery has been added to DOM');
loadScript('./assets/js/main.js', function () {
console.log('jquery use now allowed');
});
});
})();
</script>
</body>

Related

How do I load the functions of a JavaScript File called through a JavaScript Object

I have a local JS file that needs to be called using a script object. However, I am not able to get the functions to run. Here's the code snippet.
<script type="text/javascript">
var x = document.createElement("SCRIPT");
x.type = "text/javascript";
x.src = "file:///C:/scripts/localscript.js";
//one of the functions is loadData();
loadData(); //I'm getting reference error, loadData is not defined.
</script>
Thank you,
You need to create a script element and insert it in DOM (mostly under head) to load the script. When that script is loaded by the browser, whatever you return from that script will be available.
Consider sampleScript.js with below code
(function(window){
'use strict';
window.app = {
sayHi: function() {
console.log('Hey there !');
}
};
})(this);
To load this script, I do
<script>
var node = document.createElement('script');
node.src = 'sampleScript.js';
node.addEventListener('load', onScriptLoad, false);
node.async = true;
document.head.appendChild(node);
function onScriptLoad(evt) {
console.log('Script loaded.');
console.log('app.sayHi ---> ');
app && app.sayHi();
}
</script>
Taking cues, you can fit to your need. Hope this helps.
Use the onload event:
x.onload = function() { window.loadData(); }

How can I check if jquery is loaded from external JS file?

I have an external JS file to manage all script in my page.
I want to write in this file some code to check if jquery plugin is loaded and (if not) load it!
I tried to begin my myScripts.js file with this code:
if (typeof jQuery == 'undefined') {
var script = document.createElement('script');
script.type = "text/javascript";
script.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js";
document.getElementsByTagName('head')[0].appendChild(script);
}
And in my index.html
I did this:
<!DOCTYPE html>
<html lang="pt-br">
<head>
<script src="myScripts.js"></script>
</head>
<body>
<button id="test">test</button>
<script>
$('#test').click( function() {
alert('clicked');
});
</script>
</body>
</html>
But it's not performing the alert dialog.. What's wrong?
Enclose click event in $(document).ready to ensure that the event gets fired when DOM is ready.
$(document).ready(function(){
$('#test').click( function() {
alert('clicked');
});
});
When you add the jquery file using the script.it would not available so you have to add onload listener to detect the when it's available.
function fnjquery() {
$('#test').click( function() {
alert('clicked');
});
}
if(typeof jQuery=='undefined') {
var headTag = document.getElementsByTagName("head")[0];
var jqTag = document.createElement('script');
jqTag.type = 'text/javascript';
jqTag.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js';
jqTag.onload = fnjquery;
headTag.appendChild(jqTag);
} else {
fnjquery();
}
Here is a working Fiddle
function myJQueryCode() {
//Do stuff with jQuery
$('#test').click( function() {
alert('clicked');
});
}
if(typeof jQuery=='undefined') {
var headTag = document.getElementsByTagName("head")[0];
var jqTag = document.createElement('script');
jqTag.type = 'text/javascript';
jqTag.src = '//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js';
jqTag.onload = myJQueryCode;
headTag.appendChild(jqTag);
} else {
myJQueryCode();
}
<button id="test">
click
</button>

priority of the executed javascript

Say I use google map api via two sites
<head>
<script
src="https://maps.googleapis.com/maps/api/js?sensor=false&hl=zh-CN&v=3.21&callback=initMap" async defer>
</script>
<script
src="http://ditu.google.cn/maps/api/js?sensor=false&hl=zh-CN&v=3.21&callback=initMap" async defer>
</script>
</head>
<body>
<script>
function initMap() {
//something
}
</script>
</body>
Sometimes I can't connect to the first site, but the code still works. Now I want to use the first site whenever I can connect to it. Is there a way to set the priority of the two sites?
You could load the first with javascript using document.createElement and add an onerror event handler that sets the src to the second source if the first fails:
<script>
var script = document.createElement('script');
script.src = 'http://ditu.google.cn/maps/api/js?sensor=false&hl=zh-CN&v=3.21&callback=initMap';
script.onerror = function() {
// if the above source fails to load, try this one
this.src = 'https://maps.googleapis.com/maps/api/js?sensor=false&hl=zh-CN&v=3.21&callback=initMap';
this.onerror = function() {
console.log('Nothing loaded!');
}
}
script.async = true;
script.defer = true;
document.body.appendChild(script);
</script>

Dynamically loaded jQuery not defined when using inline script

Situation:
jQuery is dynamically loaded together with other scripts by one file javascripts.js in the <head> section of the html file
Each html file has it's own javascript code executed on jQuery(document).ready() in the <body> section of the html file
Problem:
Error: jQuery is not defined for javascript in the <body> section
Modifying the html file is not an option (+1000 files with same problem)
Example html file:
<html>
<head>
<title>JS test</title>
<script src="javascripts.js" type="text/javascript"></script>
</head>
<body>
<input type="text" class="date">
<script>
jQuery(document).ready(function() { // Error: jQuery not defined
jQuery('.date').datepicker();
});
</script>
</body>
</html>
javascripts.js:
// Load jQuery before any other javascript file
function loadJS(src, callback) {
var s = document.createElement('script');
s.src = src;
s.async = true;
s.onreadystatechange = s.onload = function() {
var state = s.readyState;
console.log("state: "+state);
if (!callback.done && (!state || /loaded|complete/.test(state))) {
callback.done = true;
callback();
}
};
document.getElementsByTagName('head')[0].appendChild(s);
}
loadJS('javascripts/jquery-1.8.3.min.js', function() {
var files = Array(
'javascripts/functions.js',
'javascripts/settings.js'
);
if (document.getElementsByTagName && document.createElement) {
var head = document.getElementsByTagName('head')[0];
for (i = 0; i < files.length; i++) {
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', files[i]);
script.async = true;
head.appendChild(script);
}
}
});
This is happening, as many in the comments have pointed out, because you are loading jQuery asynchronously. Asynchronous means the rest of the code is executed, and so your document-ready handler (DRH) line is running before jQuery is present in the environment.
Here's a really hacky way of resolving this. It involves making a temporary substitute of jQuery whose job is just to log the DRH callbacks until jQuery has arrived. When it does, we pass them in turn to jQuery.
JS:
//temporary jQuery substitute - just log incoming DRH callbacks
function jQuery(func) {
if (func) drh_callbacks.push(func);
return {ready: function(func) { drh_callbacks.push(func); }};
};
var $ = jQuery, drh_callbacks = [];
//asynchronously load jQuery
setTimeout(function() {
var scr = document.createElement('script');
scr.src = '//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js';
document.head.appendChild(scr);
scr.onload = function() {
$.each(drh_callbacks, function(i, func) { $(func); });
};
}, 2000);
HTML:
jQuery(document).ready(function() { alert('jQuery has loaded!'); });
Fiddle: http://jsfiddle.net/y7aE3/
Note in this example drh_callbacks is global, which is obviously bad. Ideally hook it onto a namespace or something, e.g. mynamespace.drh_callbacks.
I believe this simple solution should do the trick. The changed line in the html changes the jquery onload function to a regular function. The jquery onload function will sometimes happen before the jquery is loaded and we can't have that. It's unreliable. We need that function not to execute on page load, but AFTER the jquery has loaded.
To that end, the three lines I've added in the javascript.js are inside the code that is executed immediately after jQuery has finished loading. They test to see if the pageLoaded function has been defined (so you don't have to put one on every page, only the ones that need it) and then execute it if it's there.
Now, because the change to the HTML is simple, you can just do a regex search and replace on those 1000 files to fix them. Tools like Sublime, Eclipse or TextPad are suited for that task.
Cheers!
Example html file:
<html>
<head>
<title>JS test</title>
<script src="javascripts.js" type="text/javascript"></script>
</head>
<body>
<input type="text" class="date">
<script>
function pageLoaded() { // changed
jQuery('.date').datepicker();
} // changed
</script>
</body>
</html>
javascripts.js:
// Load jQuery before any other javascript file
function loadJS(src, callback) {
var s = document.createElement('script');
s.src = src;
s.async = true;
s.onreadystatechange = s.onload = function() {
var state = s.readyState;
console.log("state: "+state);
if (!callback.done && (!state || /loaded|complete/.test(state))) {
callback.done = true;
callback();
}
};
document.getElementsByTagName('head')[0].appendChild(s);
}
loadJS('javascripts/jquery-1.8.3.min.js', function() {
var files = Array(
'javascripts/functions.js',
'javascripts/settings.js'
);
if (document.getElementsByTagName && document.createElement) {
var head = document.getElementsByTagName('head')[0];
for (i = 0; i < files.length; i++) {
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', files[i]);
script.async = true;
head.appendChild(script);
}
}
if( typeof(pageLoaded) == "function" ){ // added
pageLoaded(); // added
} // added
});
You should try following workaround to load scripts synchronously:
function loadJS(src, callback) {
document.write('<scr'+'ipt src="'+src+'"><\/scr'+'ipt>');
callback();
}
IMPORTANT to note: this function should be called always before DOM is fully rendered.

Appending Jquery in HTML dynamically

I am new to jquery. I am trying to append Jquery in an HTML page in java. To include jquery.js file I have written following code:
scriptTag += "var script = document.createElement('script');" +
"script.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js'; " +
"script.type = 'text/javascript'; " +
"document.getElementsByTagName('head')[0].appendChild(script);" +
and then I appended following js+jquery code with it
"var script2 = document.createElement('script'); window.onload = function() {" +
"$(document).ready(function() {" +
"$(\"#identity\").hide();});};" +
"script2.type = 'text/javascript'; " +
"document.getElementsByTagName('head')[0].appendChild(script2);";
So basically I am trying to write this :
var script = document.createElement('script');
script.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js';
script.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(script);
var script2 = document.createElement('script');
window.onload = function() {
$(document).ready(function() {
$("#identity").hide();
});
};
script2.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(script2);
What I want to do is that I want my function after window load. Somehow, writing $(document).ready(function() { alone does'nt work. I get an error that $ is not defined (looks like jquery.js is not ready yet).
To avoid this problem I have used window.onload = function() {. But now I am getting error: $(document).ready is not a function. I am really confused here on how to write this thing. Is this the correct approach? Any help/guidance is highly appreciated.
[Edit]
Please note that the following code (without jquery) works fine:
window.onload = function() {
document.getElementById('identity').style.visibility='hidden';
};
[Edit]
Actually I am making a web proxy, where I download page and serve them with custom look and field. The pages does not contain any jquery files nor can I include or write HTML. I can only add my Js dynamically using java etc.
Here is some code that shows how to load a script file dynamically and also delay calling of $(document).ready until that file is loaded:
http://jqfaq.com/how-to-load-java-script-files-dynamically/
The code you use to load jquery.min.js file is called asycnhroniously. Probably this file has not been loaded at the moment you try to execute jquery function.
Therefore you should make sure that the file is loaded using a callback function.
In the following link you can find an example on how to this:
http://blog.logiclabz.com/javascript/dynamically-loading-javascript-file-with-callback-event-handlers.aspx
Also here is a working example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>index</title>
<script type="text/javascript">
function loadScript(sScriptSrc, callbackfunction) {
//gets document head element
var oHead = document.getElementsByTagName('head')[0];
if (oHead) {
//creates a new script tag
var oScript = document.createElement('script');
//adds src and type attribute to script tag
oScript.setAttribute('src', sScriptSrc);
oScript.setAttribute('type', 'text/javascript');
//calling a function after the js is loaded (IE)
var loadFunction = function() {
if (this.readyState == 'complete' || this.readyState == 'loaded') {
callbackfunction();
}
};
oScript.onreadystatechange = loadFunction;
//calling a function after the js is loaded (Firefox)
oScript.onload = callbackfunction;
//append the script tag to document head element
oHead.appendChild(oScript);
}
}
var SuccessCallback = function() {
$("#identity").hide();
}
window.onload = function() {
loadScript('http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', SuccessCallback)
};
</script>
</head>
<body>
<span id="identity"> This text will be hidden after SuccessCallback </span>
</body>
You should use this code in your scriptTag variable and then you can use eval() function to evaluate the script in this variable. Also you can load the second javascript file in the callback function using jquery's getscript function

Categories

Resources