When creating a reusable javascript library, namespacing can become a problem. It is common now the library is wrapped in a closure, and only one object becomes global. Established libraries like jQuery or Dojo have no issue, because nobody would use their base namespaces (jQuery and dojo respectively).
However, lesser known libraries can get namespace collisions. Below I describe a method to avoid these collisions, without updating the library script. This way, updates of these scripts can be deployed without a problem. First I will discuss the usage of the script. Then I will show the script itself.
When you include it like below, the namespace will be myid:
<script src="myid.js" type="text/javascript"></script>
With the added query, you get the namespace myIdentifier:
<script src="myid.js?name=myIdentifier" type="text/javascript"></script>
With the noConflict-method, you establish the same. When an other library already used the same name, the namespace is restored:
<script type="text/javascript"> myid = { is: function(id) { alert("Helo there, "+id); } }; </script> <script src="myid.js" type="text/javascript"></script> <script type="text/javascript"> myid.is('test'); // --> alert('Hello test') var myIdentifier = myid.noConflict(); myid.is('test'); // --> alert('Hello there, test') myIdentifier.is('test'); // --> alert('Hello test') </script>
The code:
new function() { var name = 'myid'; //default name var scripts = document.getElementsByTagName('SCRIPT'); if(scripts && scripts.length) { var src = scripts[scripts.length-1].src; var x = /(\?|&)name=(.+)($|&)/i.exec(src); if (x && x.length) { name = x[2]; } } var noConflict = window[name]; window[name] = { is: function(id) { alert('Hello '+id); }, noConflict: function() { var result = window[name]; if (noConflict === void 0) delete window[name]; else window[name] = noConflict; return result; } } }
The code above is run at load-time (not at onload). So the last element of the getElementsByTagName-method always returns the correct element. The only disadvantage is the script can’t be loaded with the DEFER attribute.