I've implemented this answer in order to solve my problem but I still can't get the onload event fire.
I need a javascript solution, and I'm trying this on chrome. I know that I need to check for readystate for IE.
What am I missing here?
<script>
var script = document.createElement('script');
script.type = "type/javascript";
document.getElementsByTagName('head')[0].appendChild(script);
script.onload = function(){
console.info("After loading");
mdp.video.loadAllPlayers(".videoPlaceholder");
};
script.src = "/source.min.js";
</script>
Something like that
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script type="application/javascript">
var el = document.createElement('script');
el.src = "//cdnjs.cloudflare.com/ajax/libs/less.js/1.3.3/less.min.js"; // use what ever js file you want but valid one
el.onload = function(script) {
console.log(script + ' loaded!');
};
document.body.append(el);
</script>
</body>
</html>
Related
I want to execute a script tag <script> as soon as the website load.
I tried a lot of codes but it doesn't satisfy me.
For this, you can add tag after loading page:
<script>
window.onload = function(){
var script = document.createElement('script');
script.async = "true";
script.src = "http://my-site.com/script.js";
let scriptElement = document.getElementsByTagName('script')[0];
script.parentNode.insertBefore(script, scriptElement);
}
</script>
Or you can use defer. It will be run after load page:
<script src="myLoadPage.js" defer></script>
This question already has answers here:
How to make script execution wait until jquery is loaded
(15 answers)
Waiting for dynamically loaded script
(10 answers)
Closed 9 months ago.
I use an include function to dynamically include javascript files/headers/libraries.
The problem is that it seems loading the file happens in a multi-threaded way (tested on Chrome v102) and the js file is not yet loaded when I immetiately use functionnality after that.
Example with jQuery:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf8"/>
<script type="text/javascript">
var include_once = function(url) {
/*
[additional code to check if 'url' was already included]
*/
var script = document.createElement("script");
script.type = "text/javascript";
script.src = url;
document.head.appendChild(script);
}
include_once("https://code.jquery.com/jquery-3.6.0.min.js");
</script>
</head>
<body>
<script type="text/javascript">
/*
ok if I wait 'long enough' but is arbitrary
*/
setTimeout(function(){
$(document).ready(function(){
console.log("ready (timeout)");
});
}, 10);
/*
how to wait until window.$ is defined?
*/
$(document).ready(function(){
console.log("ready");
});
</script>
</body>
</html>
This code will likely give you a $ is not defined error, and ready (timeout) will be logged to the console.
How can I make my script wait until window.$ !== undefined here ?
I tried while(window.$ === undefined) {} but it completely blocks the script and $ is never defined.
you can promisfy the loading process, by creating a promise on first script and then on the second script check if the promise is resolved.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf8"/>
<script type="text/javascript">
var isLoaded = new Promise((res,rej) => {
function include_once(url) {
/*
[additional code to check if 'url' was already included]
*/
var script = document.createElement("script");
script.type = "text/javascript";
script.onload = () => res()
script.onerror = () => rej()
script.src = url;
document.head.appendChild(script);
}
include_once("https://code.jquery.com/jquery-3.6.0.min.js");
})
</script>
</head>
<body>
<script type="text/javascript">
isLoaded.then(() => {
$(document).ready(function(){
console.log("ready");
});
})
</script>
</body>
</html>
I try to add js files dynamically.
I found several guides for that and in Page inspector, they all seem like they work…
However, I cannot reference any code in the newly added files.
My three code examples that look like they work fine... but don't.
//v1
var th = document.getElementsByTagName('head')[0];
var s = document.createElement('script');
s.setAttribute('type', 'text/javascript');
s.setAttribute('src', scriptName);
th.appendChild(s);
DevExpress.localization.loadMessages(RddsDataNavigator_LanguagePack_en);
//v2
var s = document.createElement('script');
s.setAttribute('src', scriptName);
document.head.appendChild(s);
DevExpress.localization.loadMessages(RddsDataNavigator_LanguagePack_en);
//v3
let myScript = document.createElement("script");
myScript.setAttribute("src", scriptName);
document.head.appendChild(myScript);
DevExpress.localization.loadMessages(RddsDataNavigator_LanguagePack_en);
do i have to append the scripts differently or is my reference call wrong / not possible?
the Guides that exactly explain my requirement seem somehow not to work for me ?!
https://www.kirupa.com/html5/loading_script_files_dynamically.htm
Dynamically adding js to asp.net file
Thanks in advance for any help
The three methods to add a script element are essentially the same*.
As dynamically added script elements do not load the resources synchronously, you need to listen to the load event on the global object. DOMContentLoaded is another idea, but it fires too soon as it does not wait for resources to have loaded.
Here is a demo with loading jQuery asynchronously. The output shows the type of the jQuery variable, which will be "function" once that resource is loaded:
let scriptName = "https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.js";
// v3
let myScript = document.createElement("script");
myScript.setAttribute("src", scriptName);
document.head.appendChild(myScript);
console.log("Synchronous, jQuery =", typeof jQuery);
document.addEventListener("DOMContentLoaded", function () {
console.log("After DOMContentLoaded event, jQuery =", typeof jQuery);
});
window.addEventListener("load", function () {
console.log("After load event, jQuery =", typeof jQuery);
});
* The first version also defines the type attribute, but the HTML5 specification urges authors to omit the attribute rather than provide a redundant MIME type.
Consider this working example:
// dyn.js
window.zzz = 1;
<!--index.html-->
<html>
<head>
<script>
function includeJs(url)
{
if (!url) throw "Invalid argument url";
var script = document.createElement("script");
script.src = url;
document.head.appendChild(script);
}
includeJs("dyn.js");
function documentLoaded()
{
alert(window.zzz)
}
</script>
</head>
<body onload="javascript:documentLoaded()">
</body>
</html>
An obvious difference between your code and this is that the sample above loads the script during the document loading and the usage of the script code happens after the document has finished loading.
If you need to do a late-loading of a dynamic script depending on some run-time parameters, here are some options:
If you have control over the dynamically-loading script, you could add a function in your loader script and call it at the last line of the dynamically-loading script:
// dyn.js
window.zzz = 1;
if(typeof(dynamicLoadingFinished) != "undefined") dynamicLoadingFinished();
<!--index.html-->
<html>
<head>
<script>
function includeJs(url)
{
if (!url) throw "Invalid argument url";
var script = document.createElement("script");
script.src = url;
document.head.appendChild(script);
}
function documentLoaded()
{
includeJs("dyn.js");
window.dynamicLoadingFinished = function()
{
alert(window.zzz)
}
}
</script>
</head>
<body onload="javascript:documentLoaded()">
</body>
</html>
Another possible approach would be to use the good old XMLHttpRequest. It will allow you yo either force synchronous loading (which is not advisable because it will block all JavaScript and interactivity during loading, but in certain situations can be of use):
// dyn.js
window.zzz = 1;
<!--index.html-->
<html>
<head>
<script>
function includeJs(url)
{
if (!url) throw "Invalid argument url";
var request = new XMLHttpRequest();
request.open("GET", url, false);
request.send();
var script = document.createElement("script");
script.text = request.responseText;
document.head.appendChild(script);
}
function documentLoaded()
{
includeJs("dyn.js");
alert(window.zzz)
}
</script>
</head>
<body onload="javascript:documentLoaded()">
</body>
</html>
or load the script asynchronously and wait for the request to finish:
// dyn.js
window.zzz = 1;
<!--index.html-->
<html>
<head>
<script>
function includeJs(url, finished)
{
if (!url) throw "Invalid argument url";
var request = new XMLHttpRequest();
request.open("GET", url, true);
request.onreadystatechange = function ()
{
if (request.readyState == 4 || request.readyState == 0)
{
if (request.status == "200")
{
var script = document.createElement("script");
script.text = request.responseText;
document.head.appendChild(script);
return finished();
}
else throw request.responseText;
}
};
request.send();
}
function documentLoaded()
{
includeJs("dyn.js", () => alert(window.zzz));
}
</script>
</head>
<body onload="javascript:documentLoaded()">
</body>
</html>
I believe the AJAX samples could be written also with the more modern fetch API (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).
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>
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>