Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I encapsulate third-party JavaScript files so they don't pollute the global scope?

Tags:

javascript

One of my clients is asking if they can add some JavaScript to track user behavior to their website. At first glance I fear that it is going to interfere with other third-party analytics scripts on the site because it looks like both parties have used the same JavaScript compressor. I don't want to comb through and search for every possible naming collision so . . .

Is there a way I can include third-party scripts (script files which live on a separate domain) but wrap them in their own namespace or give them their own scope so they don't collide with other globally declared variables and functions?

like image 645
Tim Christensen Avatar asked Dec 01 '10 22:12

Tim Christensen


2 Answers

In order of isolation:

  1. An (i)frame hosted on a different domain - no direct interactions possible
  2. An (i)frame hosted on the same domain - interactions only possible via explicit window/frame references
  3. A self-executing anonymous function - interactions are simple but well-behaved code can be isolated
  4. None - hope no one uses the same variable or function names

It would depend on the third-party script but I generally lean towards #2. Interactions are possible but you're insulated from casual document.write use and global namespace pollution.

Edit: Example of #2

in page.html

<div>...Your content...</div>
<iframe src="tracker.html" 
    width="10" height="10" 
    style="position:absolute; top:-100px"></iframe>

tracker.html (optionally the whole thing)

<script src="http://example.com/tracker.js"></script>

That's the basic structure but needs a little more setup or else all traffic would appear to be coming from tracker.html. For a tracking script I suggest providing the top (real) page's path in the query string to the iframe: "tracker.html?u=thispage.html". You could setup the query string either server side or via javascript:

page.html (again)

<div>...Your content...</div>
<script>
    (function(){
        var iframe = document.createElement('iframe');
        iframe.src = 'tracker.html?u=' + escape(location.href);
        iframe.width = iframe.height = 1;
        iframe.style.position = 'absolute';
        iframe.style.top = '-100px';

        var nodes = document.getElementsByTagName('script');
        var s = nodes[nodes.length - 1];
        s.parentNode.insertBefore(iframe, s);

    })();
</script>

You could optionally just use location.pathname rather than location.href (which has protocol, domain, etc.) if the path is enough for your tracking.

After all that... if the tracking script is from a reputable source (StatCounter, Google Analytics, etc.) I suggest trusting them to not step on your pages variables and functions. Options 1 and 2 are really for low trust situations.

like image 56
Cameron Jordan Avatar answered Oct 22 '22 03:10

Cameron Jordan


Like this:

(function() {
    // insert code here
})();

Enjoy ;)

like image 28
Niet the Dark Absol Avatar answered Oct 22 '22 03:10

Niet the Dark Absol