How may I reference the script tag that loaded the currently-executing script?
Solution 1
How to get the current script element:
1. Use document.currentScript
document.currentScript
will return the <script>
element whose script is currently being processed.
<script>
var me = document.currentScript;
</script>
Benefits
- Simple and explicit. Reliable.
- Don't need to modify the script tag
- Works with asynchronous scripts (
defer
&async
) - Works with scripts inserted dynamically
Problems
- Will not work in older browsers and IE.
- Does not work with modules
<script type="module">
2. Select script by id
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>
Benefits
- Simple and explicit. Reliable.
- Almost universally supported
- Works with asynchronous scripts (
defer
&async
) - Works with scripts inserted dynamically
Problems
- Requires adding a custom attribute to the script tag
-
id
attribute may cause weird behaviour for scripts in some browsers for some edge cases
3. Select the script using a data-*
attribute
Giving 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.
Benefits
- Simple and explicit.
- Works with asynchronous scripts (
defer
&async
) - Works with scripts inserted dynamically
Problems
- Requires adding a custom attribute to the script tag
- HTML5, and
querySelector()
not compliant in all browsers - Less widely supported than using the
id
attribute - Will get around
<script>
withid
edge cases. - May get confused if another element has the same data attribute and value on the page.
4. Select the script by src
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"]');
Benefits
- Reliable
- Works with asynchronous scripts (
defer
&async
) - Works with scripts inserted dynamically
- No custom attributes or id needed
Problems
- Does not work for local scripts
- Will cause problems in different environments, like Development and Production
- Static and fragile. Changing the location of the script file will require modifying the script
- Less widely supported than using the
id
attribute - Will cause problems if you load the same script twice
5. Loop over all scripts to find the one you want
We 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.
6. Get the last executed script
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>
Benefits
- Simple.
- Almost universally supported
- No custom attributes or id needed
Problems
- Does not work with asynchronous scripts (
defer
&async
) - Does not work with scripts inserted dynamically
Solution 2
Since scripts are executed sequentially, the currently executed script tag is always the last script tag on the page until then. So, to get the script tag, you can do:
var scripts = document.getElementsByTagName( 'script' );
var thisScriptTag = scripts[ scripts.length - 1 ];
Solution 3
Probably the easiest thing to do would be to give your scrip tag an id
attribute.
Solution 4
Here's a bit of a polyfill that leverages document.CurrentScript
if it exists and falls back to finding the script by ID.
<script id="uniqueScriptId">
(function () {
var thisScript = document.CurrentScript || document.getElementByID('uniqueScriptId');
// your code referencing thisScript here
());
</script>
If you include this at the top of every script tag I believe you'll be able to consistently know which script tag is being fired, and you'll also be able to reference the script tag in the context of an asynchronous callback.
Untested, so leave feedback for others if you try it.
Solution 5
Script are executed sequentially only if they do not have either a "defer" or an "async" attribute. Knowing one of the possible ID/SRC/TITLE attributes of the script tag could work also in those cases. So both Greg and Justin suggestions are correct.
There is already a proposal for a document.currentScript
on the WHATWG lists.
EDIT: Firefox > 4 already implement this very useful property but it is not available in IE11 last I checked and only available in Chrome 29 and Safari 8.
EDIT: Nobody mentioned the "document.scripts" collection but I believe that the following may be a good cross browser alternative to get the currently running script:
var me = document.scripts[document.scripts.length -1];
Admin
Updated on September 08, 2020Comments
-
Admin over 3 years
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>
-
Jason Thrasher over 13 yearsThis is simple and elegant. There's an example of it in the new Google Charts/Visualizations API if you unpack the javascript. They load JSON data from within the script tag, see: ajax.googleapis.com/ajax/static/modules/gviz/1.0/chart.js
-
Ken Smith over 12 yearsThis is a great idea, and it normally works for me. But I should add that there are times when I've found it returning a reference to a different script. Not sure why - haven't been able to track that down. Consequently, I usually go with a different method, e.g., I hard-code the name of the script file, and look for the script tag with that file name.
-
Coffee Bite over 12 yearsOne instance that I can think of where this might return incorrect results is when a script tag is added to the DOM asynchronously.
-
King Friday over 11 yearsYes this can have unpredictable results so you could try using a selector instead: $('script[src*="/mysource.js"]') ???
-
ThemeZ about 11 yearsIt doesn't work when you have scripts loaded after page loaded. You probably won't get the right tag.
-
Jos de Jong almost 10 yearsThis seems to work only for inline scripts, not for external scripts. In the latter case all properties innerText, text, and textContent are empty.
-
Royi Namir almost 10 yearsThis should be the answer.
-
Hans almost 10 yearsAgree with @RoyiNamir. This is the best answer.
-
brice almost 10 yearsThanks guys, but you know I answered 4 years after the accepted answer, right :)
-
brice almost 10 years@Josh are you trying it on the console? It's expected to be null in that case. Otherwise, that's a bug against Waterfox. Try this test page: fractallambda.com/misc/testDocumentCurrentScript
-
Nuck over 9 yearsIf you're willing to ditch IE support, you can probably express #6 even more succinctly as
document.querySelector('script:last-child').remove()
-
Christopher Weiss over 9 yearsThis is a great answer. I would like to point out that according to the HTML5 standard, id is a global attribute and may be specified on all HTML elements, including <script>. w3.org/TR/html5/dom.html#global-attributes
-
ZEE over 9 yearsGreat answer... should be answer... and StackOverflow should have a mechanism to mark the best answer... right in top of page (a star flashing with the title), so we can click on it and scrool to the answer that were marked by several users as the best!!!
-
brice over 9 years@ChristopherWeiss I stand corrected! Can't remember where I read that
id
attributes would be problematic on scripts inside the<head>
. Probably a renderer-specific issue, rather than spec issue. -
neeagl over 9 yearsHow to make it work when the script loads in an async way? I am looking to get the GET parameters.
-
jakub.g almost 9 yearsNote this thing works if you query for self directly in the script main scope. If you do it in a method, other scripts may get loaded in the meantime and distort this.
-
nichochar over 8 yearsAlthough you are right, there are lot's of cases in which the OP's question are valid, a couple would be: 1) when you're crawling 2) when you are working with the DOM of a client, and he is unwilling to change
-
xwild about 8 years"document.currentScript" doesn't work for me with dynamic loaded scripts, returns null in the latest chrome/firefox, "last executed script" works ok
-
Supersharp about 7 yearsdoesn't work when
script
is in atemplate
inserted in a Shadow DOM -
Moritz almost 7 yearsIt's document.scripts not document.script
-
Gary99 almost 7 yearsWelcome to Stack Overflow. Would you care to include some code with the algorithm?
-
LSOJ almost 7 yearsThar you go, @Gary99
-
robsch over 6 yearsWhich option should I use? I'd like to pass some parameters with data-* attributes to the script. Now I'm wondering if this is a good idea. Is there not jQuery option that does the magic?
-
Psyrus over 6 yearsFull respect to @brice for being humble with his comment about 4 years after accepted answer (I make this comment 9 years after post and have no idea where that accepted answer has gone...). This is a superb answer and helped me considerably. This is the SO community that makes it work so well - producers re-answering old posts with these type of answers benefit consumers like myself who stumble upon these archaic posts and glean valuable nuggets. Thank you kind sir!
-
n.r. over 6 yearsThe
id
attribute is invalid in ascript
element though. What sorts of problems could this approach generate? -
Spencer O'Reilly over 6 yearsSince Javascript is often event based then any of the scripts in the array have an equal chance of being the currently executing script, don't they?
-
Travis Tidwell over 5 yearsI have found that this does not always work. It is better to add a reverse find script instead. var scripts = document.getElementsByTagName('script'); var thisScript = null; var i = scripts.length; while (i--) { if (scripts[i].src && (scripts[i].src.indexOf('yourscript.js') !== -1)) { thisScript = scripts[i]; break; } }
-
Fabian von Ellerts over 5 yearsVery outdated. This can be done with the querySelector, a simple oneliner!
-
T.J. Crowder almost 5 years@n.r. - No, all elements can have an
id
attribute.id
,class
, andslot
are defined at the DOM level, not the HTML level. If you go to the global attributes in HTML and scroll past the list, you'll find "DOM standard defines the user agent requirements for the class, id, and slot attributes for any element in any namespace." followed by "The class, id, and slot attributes may be specified on all HTML elements." The DOM spec covers it here. -
Luca C. almost 5 yearsWARNING: this is true only if you don't use asynch or defer
-
den232 over 4 yearsAs of 2019-Oct, document.currentScript still returns null in latest Chrome.
-
brice over 4 years@den232 - Are you trying this in the console? This is expected to return null. Try it by embedding the script on a test page to get the right behaviour in chrome. Try this test page: fractallambda.com/misc/testDocumentCurrentScript
-
den232 over 4 years@brice - Of course. You are sooo right. my duh. Thanks jb
-
Leo about 4 yearsdocument.currentScript returns null in a shadow DOM in Chrome today.'
-
user2880616 about 4 yearsFor those using option #2 with jQuery, note that $("#myscript") does not work while the script is executing but you can use $(document.getElementById('myscript'))
-
DrSensor over 2 yearsIf it's
type="module"
,import.meta.url
can make "select by src" approach more reliable. However, it still suffer the problem when a file.js src in many <script> tag.