After being told by several folks it wasn't possible, I actually figured out a way (shown below), so
- I'm posting it so others may benefit, and
- You can tell me if there are any potential bugs.
- You can tell me if there's a better way.
Include the following snippet in the first line of your .js file:
Expand|Select|Wrap|Line Numbers
- var thisScript = (function(){
- var ScriptID = "ScriptID" + Math.round(100000*Math.random());
- document.write("<script id='"+ScriptID+"'></script>");
- return document.getElementById(ScriptID).previousSibling.getAttribute("src");
- })()
- alert(thisScript);
Tested in IE 7, Firefox 2, Safari 3
HOW IT WORKS:
First off, we generate a random ID. Next, we use document.write to create a bogus <SCRIPT> tag in the DOM (we can't use DOM commands here because the page is still streaming and DOM doesn't fully exist)
That done, we now look for the bogus tag, knowing that its previous sibling *must* be the currently-executing <SCRIPT> tag. (Amazingly, even though DOM isn't fully written yet, this still works).
Finally, we just grab the src attribute of the current <SCRIPT>, and we have our answer. Any functions that reference the global thisScript will automatically know their own filepath.
If you are dealing with multiple JS files, just vary the name of thisScript (thisScript1, thisScript2, etc), or else reference thisScript within a closure function to capture its state at the time it was executed.
I wrapped the whole thing in a null closure, so the function and all variables it creates garbage-collect the moment it runs, to avoid stepping on any existing code. All that remains is the var you assigned along with its value.