About
This page shows you how you can load a script dynamically with Javascript to load and use it when needed.
List
With Pure Javascript
In short, if you add:
- a script via a html fragment (ie as html text), it will not be executed. (via InnerHTML or insertAdjacentHTML)
Module loading with Script Element insertion
const head = document.querySelector('head');
const scripts = [
["https://cdnjs.cloudflare.com/ajax/plugins/toolbar/prism-toolbar.js","sha256-kK4/JIYJUKI4Zdg9ZQ7FYyRIqeWPfYKi5QZHO2n/lJI="],
["https://cdn.example.com/script.js","integrityHash"],
];
scripts.forEach(scriptRow => {
let script = document.createElement('script');
script.src=scriptRow[0];
script.integrity=scriptRow[1];
script.crossOrigin="anonymous";
head.append(script);
script.addEventListener("load", function(){
console.log("The script has loaded and is usable");
})
}
)
For more loader, see the page: Javascript - Module Loader (Script Loader)
Inline script loading with Script Element
- Inserting a DOM node with appendChild
let script = document.createElement('script');
script.text="console.log('hello foo');";
document.body.appendChild(script);
Inline script loading with HTML Fragment
Inserting a HTML fragment will not execute any script element.
The solution is that you need:
- for a src script element (the src attribute has an url):
- to clone the inserted script element
- for a inline script element (without an src attribute but with content):
- to clone the inserted script element
- or evaluate its content
The below example shows you a clone example. We insert a fragment with insertAdjacent
let htmlFragment = "<script>console.log('hello world');<\/script>";
// we have escape the closing script ie <\/script> because this code run in a script element
document.body.insertAdjacentHTML('afterbegin', htmlFragment);
- and we can see that there is no console output, the code was not executed
But when we clone and insert it as element, it will be:
- The clone function
let cloneScriptElement = function(element){
let clone = document.createElement(element.localName);
clone.text = element.text
Array.from(element.attributes).forEach( attr => clone.setAttribute(attr.name, attr.value) );
return clone;
}
- The replacement
let script = document.body.querySelector("script"); // the first node after the body
let clone = cloneScriptElement(script );
script.parentNode.replaceChild(clone, script);
- The console has now an output.
Via the import statement
Via a dynamic import statement.
Example:
import('https://cdn.jsdelivr.net/npm/[email protected]/dist/moment.js').then( ({ default: moment}) => {
const now = moment().format();
console.log(`The actual time is "${now}"`);
});
Via Browser Module Loader
browser module loader are libraries that manage the loading of modules and their dependencies.
Example with RequireJs
In this example, we will load the bowser UMD library in order to get information about your browser.
- Adding the require library in your HTML page
<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.6/require.min.js" integrity="sha512-c3Nl8+7g4LMSTdrm621y7kf9v3SDPnhxLNhcjFJbKECVnmZHTdo+IRO05sNLTH/D3vA6u1X32ehoLC7WFVdheg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
- Require and run
require(['https://cdnjs.cloudflare.com/ajax/libs/bowser/2.11.0/bundled.min.js'], function(bowser) {
const browser = bowser.getParser(window.navigator.userAgent);
console.log(`Your browser name is "${browser.getBrowserName()}"`);
});
- Output:
Via workers
It's also possible to offload the loading of scripts to workers.
Example: https://partytown.builder.io/