Skip to content

Instantly share code, notes, and snippets.

@MattSurabian
Last active June 10, 2016 14:42
Show Gist options
  • Save MattSurabian/169541b3d28a9320e61afa943dd56eda to your computer and use it in GitHub Desktop.
Save MattSurabian/169541b3d28a9320e61afa943dd56eda to your computer and use it in GitHub Desktop.

The CoreMetrics analytics library can be asychronously loaded; their knowledge base provides an example implementation that may not function as intended if it is used exactly as written:

<body>
<script type='text/javascript'>
var cmTagQueue = cmTagQueue || [];
cmTagQueue.push(['cmSetClientID', '99999999', false, "testdata.coremetrics.com", "mysite.com"]);
cmTagQueue.push(['cmCreatePageviewTag','AsyncTestPageID','AsyncTestPageID']);
</script>
<script type='text/javascript'>
(function() {
 var cm = document.createElement('script');
 cm.type = 'text/javascript';
 cm.async = true;
 cm.src = ('https:' == document.location.protocol ? 'https:' : 'http:') +
 '//libs.coremetrics.com/eluminate.js';
 (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(cm);
})
();
</script>
</body>

Note that the operating context here is an HTML document and in the first script tag javascript is written outside of any function body. Whenever a variable statement occurs outside of a function body that variable's name is exposed to the global scope, which in this case is window.

In that snippet this:

var cmTagQueue = cmTagQueue || [];

is equivalent to this:

var window.cmTagQueue = window.cmTagQueue || [];

Likewise when the snippet references a variable like this:

cmTagQueue.push(['cmSetClientID', '99999999', false, "testdata.coremetrics.com", "mysite.com"]);

the browser sees:

window.cmTagQueue.push(['cmSetClientID', '99999999', false, "testdata.coremetrics.com", "mysite.com"]);

Depending on your level of familiarity with this type of thing that may be non-obvious behavior. Unless you are implementing CoreMetrics exactly as the snippet shows, that is totally contained in an HTML document, copying only the javascript from their provided example and using it as-is could result in unexpected problems, especially if it ends up being bundled or otherwise executed inside the limited scope of a function block. To account for that use this snippet instead, which is explicit about its reliance on global variables:

var window.cmTagQueue = window.cmTagQueue || [];
window.cmTagQueue.push(['cmSetClientID', '99999999', false, "testdata.coremetrics.com", "mysite.com"]);
window.cmTagQueue.push(['cmCreatePageviewTag','AsyncTestPageID','AsyncTestPageID']);

(function() {
 var cm = document.createElement('script');
 cm.type = 'text/javascript';
 cm.async = true;
 cm.src = ('https:' == document.location.protocol ? 'https:' : 'http:') +
 '//libs.coremetrics.com/eluminate.js';
 (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(cm);
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment