Looks like I found a solution for your problem. I wouldn't suggest it, but it's the only way you can load an external script from another one before the DOMContentLoaded
event fires.
Solution
Since that your main.js
script is in the <head>
of your document, you can be sure that it will be loaded and executed before any following part of the DOM. Given this, you can use a synchronous XMLHttpRequest
to load your script and execute it.
This kind of technique has some pros and cons:
Pros: you can load and execute any script before DOMContentLoaded
, and also multiple scripts sequentially.
Cons: your document will be frozen until the requests are completed.
Not that bad, if your script isn't enormous it will not drastically impact the loading time. We can still do it.
Implementation
First of all, make sure that your custom.js
script is served over a link which will always be reachable, so that your request will not fail. Also make sure that your main.js
script hasn't got async
or defer
properties, so that it will always be executed in the <head>
, before the DOMContentLoaded
event.
<!-- NOT GOOD -->
<script src="main.js" defer></script>
<script src="main.js" async></script>
<!-- GOOD :) -->
<script src="main.js"></script>
Now that you're ready, in your main.js
script you'll need to:
Create and initialize a synchronous XMLHttpRequest
object, and send()
a GET
request to your content.js
script.
Create a <script>
element, and put the result of your request (which is stored in the .responseText
property of the request object) inside it.
Append the script to the <head>
to make it run before the DOM is loaded.
Plus, if you also want your script to be removed right after execution (so it will not be visible to the users), you can:
- Remove the
<script>
from the document after it has ran its code. You'll need to listen for the onload
event for this.
Also, if you want to make your code run completely anonymously, you can wrap it inside an anonymous function
to prevent the access to it from the global scope.
Here's a quick example of what you'll need to do in your main.js
file:
(function() {
// Create the request and the script
var xhr = new XMLHttpRequest(),
s = document.createElement('script');
// Send the request to retrieve custom.js
xhr.open('GET', 'path/to/custom.js', false);
xhr.send();
// Listen for onload, and remove the script after execution
s.addEventListener("load", function(e) {
s.parentElement.removeChild(s);
});
// Load the code inside the script and run it in the head
s.textContent = xhr.responseText;
document.head.appendChild(s);
})();
Now your custom.js
script will (anonymously) run before DOMContentLoaded
, mission complete!