How can I reference the script element that loaded the javascript that is currently running?
Here's the situation. I have a "master" script being loaded high in the page, first thing under the HEAD tag.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script type="text/javascript" src="scripts.js"></script>
There is a script in "scripts.js" which needs to be able to do on-demand loading of other scripts. The normal method doesn't quite work for me because I need to add new scripts without referencing the HEAD tag, because the HEAD element hasn't finished rendering:
document.getElementsByTagName('head')[0].appendChild(v);
What I want to do is reference the script element that loaded the current script so that I can then append my new dynamically loaded script tags into the DOM after it.
<script type="text/javascript" src="scripts.js"></script>
loaded by scripts.js--><script type="text/javascript" src="new_script1.js"></script>
loaded by scripts.js --><script type="text/javascript" src="new_script2.js"></script>
document.currentScript
document.currentScript
will return the <script>
element whose script is currently being processed.
<script>
var me = document.currentScript;
</script>
defer
& async
)<script type="module">
Giving the script an id attribute will let you easily select it by id from within using document.getElementById()
.
<script id="myscript">
var me = document.getElementById('myscript');
</script>
defer
& async
)id
attribute may cause weird behaviour for scripts in some browsers for some edge casesdata-*
attributeGiving the script a data-*
attribute will let you easily select it from within.
<script data-name="myscript">
var me = document.querySelector('script[data-name="myscript"]');
</script>
This has few benefits over the previous option.
defer
& async
)querySelector()
not compliant in all browsersid
attribute<script>
with id
edge cases. Instead of using the data attributes, you can use the selector to choose the script by source:
<script src="//example.com/embed.js"></script>
In embed.js:
var me = document.querySelector('script[src="//example.com/embed.js"]');
defer
& async
)id
attributeWe can also loop over every script element and check each individually to select the one we want:
<script>
var me = null;
var scripts = document.getElementsByTagName("script")
for (var i = 0; i < scripts.length; ++i) {
if( isMe(scripts[i])){
me = scripts[i];
}
}
</script>
This lets us use both previous techniques in older browsers that don't support querySelector()
well with attributes. For example:
function isMe(scriptElem){
return scriptElem.getAttribute('src') === "//example.com/embed.js";
}
This inherits the benefits and problems of whatever approach is taken, but does not rely on querySelector()
so will work in older browsers.
Since the scripts are executed sequentially, the last script element will very often be the currently running script:
<script>
var scripts = document.getElementsByTagName( 'script' );
var me = scripts[ scripts.length - 1 ];
</script>
defer
& async
)