In a recent project I had a situation where it was needed to display a Google Map to the user. But, due to certain legal obligations, it could not be done by default, but the Google Map would only be loaded once the user provides consent that he agrees to download data from 3rd party providers.
This needed to be done using only HTML and Javascript. If user consent was not explicitly given, the Google Map script should not be loaded. So, I needed to add the
<script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap"></script>
but only after the consent was given.
The trick is the script can only be loaded after the consent is given, so it cannot be included in the initial HTML code. How to get around this? Well, it is fairly easy once you think about it: using the document.createElement function you just create a new <script> tag and append it to the <head> element of the HTML file:
var head = document.getElementsByTagName('head')[0]; var js = document.createElement("script"); js.type = "text/javascript"; js.src = 'https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap'; head.appendChild(js);
This will load the JS file only once the code is run. Do note that the code is asynchronous, the Javascript will keep running other commands while the script is being loaded. However, Google Maps does have the callback parameter with the initMap function which will trigger once the loading of the Javascript file is complete, and there you can use the window.google object any way you like.
Some JS files (like Google Maps) are included via an API that provides a callback function. But what if you just request a basic Javascript file and have no way to pass the callback through an URL (like you do with Google Maps)?
There is a solution for this as well. You just connect a callback function of your own the onload event of the new element you created for the <script> tag.
function appendScriptToHeadElementAndAddCallbackFunction (src, callbackFunction) { var head = document.getElementsByTagName('head')[0]; if (head) { var js = document.createElement("script"); js.type = "text/javascript"; js.src = src; head.appendChild(js); } else { throw "No <head> element found."; } if (callbackFunction != null) { js.onload = callbackFunction; } }
Then you would do something like:
function myFunction () { console.log("Loaded!"); } function onConsentGiven () { appendScriptToHeadElementAndAddCallbackFunction("MyScript.js", myFunction); }
If you want to load a Javascript file on demand, there are two basic steps:
You can find a demo on my GitHub showing a few basic cases so you can easily spot the differences.
EDIT:
Updated the article after Neno’s comment removing the “onreadystatechange” event. Thanks, Neno!
You are currently offline
Is onreadystaGechange a typo of onreadystaTechange? If so, it seems like onreadystatechange is only available to XMLHttpRequest objects and not DOM nodes. Am I missing something?
Hey, Neno,
Only saw this comment now. You are absolutely right, I updated the article accordingly. Thanks for catching that one!