I need to include jQuery in js file since it would be loaded as a external script.
Here is my code:
function addjQuery() {
if (!window.jQuery) {
var jq = document.createElement("script");
jq.type = "text/javascript";
jq.src = "https://code.jquery.com/jquery-3.2.1.min.js";
document.getElementsByTagName("head")[0].appendChild(jq);
console.log("Added jQuery!");
} else {
console.log("jQuery already exists.")
}
}
addjQuery();
jQuery(function($) {
$(document).ready(function() {
});
});
But error occurs:
Uncaught ReferenceError: jQuery is not defined
Even when I run "jQuery" or "$" on console of chrome dev tool, it's working.
What's the problem?
The jQuery() function is firing prior to jQuery being loaded from the script tag - you can add an onload event handler to fire it when the script is done downloading:
function addjQuery() {
if (!window.jQuery) {
var jq = document.createElement("script");
jq.type = "text/javascript";
jq.src = "https://code.jquery.com/jquery-3.2.1.min.js";
document.getElementsByTagName("head")[0].appendChild(jq);
jq.onload = initjQuery;
console.log("jQuery is loaded!");
} else {
console.log("jQuery already exists.")
}
}
function initjQuery () {
jQuery(function($) {
$(document).ready(function() { });
});
}
addjQuery();
Related
i am injecting various script's and css from chrome extension, below is my snippet code,
Background.js
function start() {
var tab = JSON.parse(localStorage.getItem('tab'));
chrome.tabs.insertCSS(tab.id, { file: 'assets/css/style.css' })
chrome.tabs.executeScript(tab.id, { file: 'assets/lib/jquery-1.8.2.min.js' }, function () {
chrome.tabs.executeScript(tab.id, { file: 'assets/lib/jquery-ui.min.js' }, function () {
chrome.tabs.executeScript(tab.id, { file: 'js/inject/inject.js'});
});
});
}
chrome.browserAction.onClicked.addListener(function (tab) {
start();
});
Inject.js
(function(){
jQuery(document).ready(function () {
console.log("Document Loaded!!");
jQuery("#Table td").click(function() {
var column_num = parseInt( $(this).index() ) + 1;
var row_num = parseInt( $(this).parent().index() )+1;
console.log(column_num, row_num);
});
});
})();
now the problem is that when i am opening extension second time jQuery stops working and throwing error of
Uncaught TypeError: jQuery is not a function
or
Uncaught TypeError: jQuery is undefined
I need to find if it is possible to check that my inject.js has already been executed then on reopening extension i just need to call other functions.
I am using Google API, based on their link I have to put the following script in the HTML file
<script src="https://apis.google.com/js/client.js?onload=callback"></script>
The custom callback function is being loaded after the client.js is loaded successfully.
function callback() {
var ROOT = 'https://your_app_id.appspot.com/_ah/api';
gapi.client.load('your_api_name', 'v1', function() {
doSomethingAfterLoading();
}, ROOT);
}
I would like to
Separate HTML with JS file
I downloaded the client.js file and put it in my local repo. But for reducing web request I would like to concat the client.js with other JS file. But I have no idea how to load the content with the concatenated JS file with the callback is being called
Thanks in advance
If you are looking for javascript only solution:
var sScriptSrc = "https://apis.google.com/js/client.js?onload=callback"
loadScript(sScriptSrc);
function loadScript(sScriptSrc) {
var oHead = document.getElementsByTagName("HEAD")[0];
var oScript = document.createElement('script');
oScript.type = 'text/javascript';
oScript.src = sScriptSrc;
oHead.appendChild(oScript);
oScript.onload = loadedCallback();
}
function loadedCallback() {
alert("WoHooo I am loaded");
}
See it running here: JSFiddle
EDIT
Let me do some refining, if I understand correctly what you want to achieve:
I made a simple main html page:
<html>
<head>
<script src="client.js"></script>
</head>
<body>
PAGE BODY
</body>
</html>
Which is loading client.js
client.js contains:
// you can call this function with
// param1: src of the script to load
// param2: function name to be executed once the load is finished
function loadScript(sScriptSrc, loadedCallback) {
var oHead = document.getElementsByTagName("HEAD")[0];
var oScript = document.createElement('script');
oScript.type = 'text/javascript';
oScript.src = sScriptSrc;
oHead.appendChild(oScript);
oScript.onload = loadedCallback;
}
// let's load the Google API js and run function GoggleApiLoaded once it is done.
loadScript("https://apis.google.com/js/client.js", GoggleApiLoaded);
function GoggleApiLoaded() {
alert("WoHooo Google API js loaded");
}
Of course, instead of GoggleApiLoaded example function you could run a method which start the loading of different js and the callback of that one could load a next one and so on...
Is this what you were looking for?
jQuery has a nice method for this. https://api.jquery.com/jquery.getscript/
jQuery.getScript("https://apis.google.com/js/client.js", function() {
console.log("hello");
})
If you want to be compatible with IE, including IE 9, you can use this async JS file loader & callback:
function loadAsync(src, callback){
var script = document.createElement('script');
script.src = src;
script.type = 'text/javascript';
script.async = true;
if(callback != null){
if (script.readyState) { // IE, incl. IE9
script.onreadystatechange = function() {
if (script.readyState == "loaded" || script.readyState == "complete") {
script.onreadystatechange = null;
callback();
}
};
} else {
script.onload = function() { // Other browsers
callback();
};
}
}
a=document.getElementsByTagName('script')[0];
a.parentNode.insertBefore(script,a);
}
loadAsync("https://www.example.com/script.js", callbackFunction);
function callbackFunction() {
console.log('Callback function run');
}
I try to write a JavaScript function that loads a js script (src) and performs some callback when the script is loaded.
I also look if a script with the same src already exists.
My problem is that if the script already loaded, the callback will not be performed. That is NOK.
How to know if the script was already loaded?
importScript: (function (head) {
function loadError(error) {
throw new URIError("The script " +
error.target.src + " is not accessible.");}
return function (url, callback) {
var existingScript = document.querySelectorAll("script[src='" +
url + "']");
var isNewScript = (existingScript.length == 0);
var script;
if (isNewScript) {
script = document.createElement("script")
script.type = "text/javascript";
}
else {
script = existingScript[0];
}
script.onerror = loadError;
if (script.readyState) { //IE
script.onreadystatechange = function () {
if (script.readyState == "loaded" ||
script.readyState == "complete") {
script.onreadystatechange = null;
if (callback) {
callback(); }
}
};
} else { // others than IE
script.onload = callback; }
if (isNewScript) {
script.src = url;
head.appendChild(script); }
}
})(document.head || document.getElementsByTagName("head")[0])
As I understand, the script.readyState == "loaded" || script.readyState == "complete" could work only for IE, not for other browsers as well...
Usage:
importScript("myScript1.js");
importScript("myScript2.js", /* onload function: */
function () { alert("The script has been OK loaded."); });
I recommend jQuery, it's so easy with that. Life is too short for coding things like that yourself (you will waste hours for supporting all browsers).
$.ajax({
url: "/script.js",
dataType: "script",
success: function() {
console.log("script loaded");
}
});
EDIT:
It's even easier (example from jQuery docs):
$.getScript( "ajax/test.js", function( data, textStatus, jqxhr ) {
console.log(data); // Data returned
console.log(textStatus); // Success
console.log(jqxhr.status); // 200
});
You can also chain done and fail to have additional callbacks:
$.getScript("ajax/test.js")
.done(function(script, textStatus) {
console.log(textStatus);
})
.fail(function(jqxhr, settings, exception) {
console.log("loading script failed.");
});
Load jQuery asynchronously
<script src="path/to/jquery"></script>
<script>
function wait(method) {
if (window.$) {
method();
} else {
setTimeout(function () { wait(method); }, 100); // check every 100ms
}
}
// wait for jQuery
wait(function() {
// jQuery has loaded!
$("#foo").doSomething();
// you can now load other scripts with jQuery:
$.getScript("ajax/test.js")
.done(function(script, textStatus) {
console.log(textStatus);
})
.fail(function(jqxhr, settings, exception) {
console.log("loading script failed.");
});
}
</script>
Well the safest way to check if script is loaded is you can add a simple callback at end of script . Which if exist can be called with some data also to be passed.
if(window.loaded){
window.loaded(params);
}
Once the script loads it will execute this method which you can declare in your parent script which will be called.
Also you can trigger an event on body and listen on that event in other parent code.
Based on method from Luca Steeb, I refine the solution to just two script tags, for SPA applications, index.html is very compact with:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Simplified INDEX</title>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script src="/bootloader.js"></script>
</head>
<body>
</body>
</html>
bootloader.js, combine ideas from Luca and load css using jquery :
function loadScripts() {
// jQuery has loaded!
console.log("jquery is loaded");
// you can now load other scripts and css files with jQuery:
$.when($.getStylesheet('css/main.css'), $.getScript('js/main.js'))
.then(function () {
console.log('the css and js loaded successfully and are both ready');
}, function () {
console.log('an error occurred somewhere');
});
}
function patchGetStylesheet($) {
$.getStylesheet = function (href) {
var $d = $.Deferred();
var $link = $('<link/>', {
rel: 'stylesheet',
type: 'text/css',
href: href
}).appendTo('head');
$d.resolve($link);
return $d.promise();
};
}
function wait(method) {
if (window.$) {
patchGetStylesheet(window.$);
method();
} else {
setTimeout(function () {
wait(method);
}, 100); // check every 100ms
}
}
// wait for jQuery
wait(loadScripts);
For bootloader.js, it could be minified、obfused.... using webpack, ...
We will not add code to index.html any more through solving runtime dependency using jquery.
My script will be using as widget in third-party website so i don't aware about jquery loaded and which version of jquery loaded or not at third-party end.
So Before loading below script i want to check is there already latest jquery 1.11.1 loaded after dom ready if not then i want to load the jquery latest and run below script.
script.js
var $ = jQuery.noConflict( true );
(function( $ ) {
$(document).ready(function() {
alert("Document Ready ");
});
})($jy);
EDIT 1
var addNewJQuery = function() {
(function( $ ) {
$jy = $;
var invokeOriginalScript;
$(document).ready(function() {
......my code here.....
}):
})(jQuery);
}
Not sure if this is working for you, but it looks like it is working.
Maybe you need to remove the other script from your header after you loaded the second jQuery file. But it seems to work with both scripts loaded.
I've also added a check if jQuery is loaded at all, if not it will load jQuery.
You can also find the same code in this fiddle.
var addNewJQuery = function() {
//var jQ = jQuery.noConflict(true);
(function ($) {
$(document).ready(function () {
alert("You are now running jQuery version: " + $.fn.jquery);
});
})(jQuery);
};
if ( typeof jQuery === 'undefined' ) {
alert('no jQuery loaded');
//throw new Error("Something went badly wrong!"); // now you could load jQuery
loadScript('https://code.jquery.com/jquery-1.11.2.js', addNewJQuery);
}
if ($.fn.jquery !== '1.11.2') {
console.log('detected other jQuery version: ', $.fn.jquery);
loadScript('https://code.jquery.com/jquery-1.11.2.js', addNewJQuery);
}
function loadScript(url, callback)
{
// Adding the script tag to the head as suggested before
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
// Then bind the event to the callback function.
// There are several events for cross browser compatibility.
script.onreadystatechange = callback;
script.onload = callback;
// Fire the loading
head.appendChild(script);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
I have a TextBox and a Button:
If the value inside the Textbox is 1 (just emulating a condition)) I need to load jQuery on the fly and use a document Ready function :
I tried this :
function work() //when button click
{
if (document.getElementById('tb').value == '1')
{
if (typeof jQuery == 'undefined')
{
var script = document.createElement('script');
script.src = "http://code.jquery.com/jquery-git2.js";
document.getElementsByTagName('head')[0].appendChild(script);
$(document).ready(function ()
{
alert('');
});
}
}
}
But it says :
Uncaught ReferenceError: $ is not defined
I assume it's because the line : $(document).ready(function ()....
But I don't understand why there is a problem , since i'm, loading jQuery BEFORE I use $...
Question :
How can I fix my code to work as desired ?
JSBIN
You are missing the script onload handler:
var script = document.createElement('script');
// do something with script
// onload handler
script.onload = function () {
// script was loaded, you can use it!
};
Your function becomes:
function work() {
if (document.getElementById('tb').value != '1') { return; }
if (typeof jQuery != 'undefined') { return; }
// jQuery is undefined, we will load it
var script = document.createElement('script');
script.src = "http://code.jquery.com/jquery-git2.js";
document.getElementsByTagName('head')[0].appendChild(script);
// load handler
script.onload = function () {
// jQuery was just loaded!
$(document).ready(function () {
alert('');
});
};
}
Also, do not forget script.onreadystatechange for IE compatibility.
script.onreadystatechange = function () {
if (script.readyState === 'loaded' || script.readyState === 'complete') {
// script was loaded
}
}
Also seems that YepNope would be a good option, too.
JSBIN DEMO
Using YepNope would probably a good option in this case.
yepnope([
{
test: window.jQuery,
nope: 'path/url-to-jquery.js',
complete: function() {
$(document).ready(function() {
//whatever you need jquery for
});
}
}
]);
You can just put that in the head of your document, and it will only load jquery if window.jQuery isn't defined. It's much more reliable (and simpler) than script.onload or script.onreadystatechange. the callback complete will only be called once jquery is loaded, so you can be sure that $ will be defined at that point.
Note: if you're using Modernizr.js on your site, there's a good chance yepnope is already bundled into that script.