Thursday, October 17, 2013

Read current script tag in Javascript

Today I was asked simple question - How to read current JavaScript tag in JS code itself. Sounds easy, and usefull when you want to provide JS snippet that does some sort of DOM modificaiton, ideal for example ad delivery where ad-script tag will be transformed into DIV or SPAN dom element. However, initially there were couple of ideas:

  • Mark script tag with specific ID. This idea fails at the beginning because, it's hard to distinguish source tag if you have multiple snippets with same src url inserted into page
  • Mark script tag with specific code comment, and match in code markup text against specific regex expression. Still fails if you don't put some extra info in code comment, that will make 2 or more scripts distinct. 
Perfect solution is more than simple: since included JavaScript tags are always executed sequentially, in the time of execution of current script all tags included below given tag are not visible to the DOM model, so we could just say 'give me last loaded script tag'. Take a look at code below

//read all script tags, and get last one
var getCurrentScriptTag = function(){
 var scripts = document.getElementsByTagName('script');
 var lastScript = scripts[scripts.length - 1];
 return lastScript
}

//global counter, if not definet set to 0
window.scriptCounter = (window.scriptCounter ) || 0;
//increment
window.scriptCounter++;

//mark last script tag
getCurrentScriptTag().setAttribute('id','script-' + scriptCounter);

Every time script file is loaded, variable called scriptCounter is incremented, or set to 0  if that's the first time script loads, and variable hasn't been initialized before. Now consider including above script several times on a page:


 
 <script type="text/javascript" src="script1.js"> </script>
 <script type="text/javascript" src="script1.js"> </script>
 <script type="text/javascript" src="script1.js"> </script>
 <script type="text/javascript" src="script1.js"> </script>
 

So, what's the resulting DOM after the page is loaded. Note that every time script is loaded, it's execution isn't attached to any document 'load', or 'ready' event, it's executed right away, so above written getCurrentScriptTag() function works as expected:

I hope this small post helps someone solve real-world problem!