我正在构建一个Google Analytics特色平台,该平台可以使用非常标准的流程:
在研究了各种公司如何处理上述流程的几种不同实现之后,我发现Google的新Universal Analytics tag似乎具有最优雅的执行,原因如下:
似乎允许用户在主库仍然异步加载时进行方法调用,所有这些都在<script type="text/javascript">
个标记内。
这方面的一个例子是Quick Start Code:
<!-- Google Analytics -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-XXXX-Y', 'auto');
ga('send', 'pageview');
</script>
<!-- End Google Analytics -->
我正在尝试理解它如何允许用户调用ga('create' ... )
和ga('send' ... )
,而主匿名函数仍然可能操纵DOM并插入/下载analytics.js
脚本。
有人知道上述模式是如何运作的吗?
尝试对其缩小代码进行逆向工程似乎表明它们可能正在创建一个空白ga
对象,该对象在主库加载之前有效地充当消息队列。然后,当库加载时,它看起来正在解析队列对象并执行它需要做的事情(因为它将能够实际执行其任务,因为库已加载)。
我不能100%确定上述内容是否正确,因为对所有代码进行逆向工程有点棘手。
我创建了一个类似的实现,其中我使用window.tempDataWhileLibraryHasntLoaded
对象来存储在加载库之前由ga("send" ...)
之类的方法调用的所有数据。然后库解析此对象,处理它需要的内容to,并使对象为空,但这看起来并不像Google的实现一样干净。
答案 0 :(得分:3)
因此解开缩小的脚本,它看起来像这样(删除了插入脚本标记的代码):
window.GoogleAnalyticsObject = 'ga';
window.ga = window.ga || function(){
( window.ga.q = window.ga.q || [] ).push(arguments);
}
window.ga.l = 1 * new Date();
他们创建window.ga
并将其分配给将任何参数推送到数组window.ga.q
中的函数。 ||或者运营商在那里确保如果已经创建了东西就不会被覆盖。
因此,当您调用ga('foo', 'bar')
时,它只是将这些参数存储在数组中。当脚本加载后,它将查找window.ga.q
数组并循环其值,找到'foo'和'bar'并在加载的脚本中调用相应的函数。