Google Analytics代码说明

Mil*_*tin 33 javascript google-analytics

有人可以"逐步","逐行"解释这段代码吗?我想了解更多关于Asynch代码以及Google如何加载他们的脚本,如何从用户"隐藏"javascrippt(我知道我无法隐藏它但至少让它像Google那样,不显示所有代码)一个档案)

<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-xxxxxxxx-x', 'xxxxxx.com');
  ga('send', 'pageview');
</script>
Run Code Online (Sandbox Code Playgroud)

Zla*_*tev 80

首先,我会通过一个美化器,例如http://jsbeautifier.org/

 (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-xxxxxxxx-x', 'xxxxxx.com');
 ga('send', 'pageview');
Run Code Online (Sandbox Code Playgroud)

之后让我们评估一下

(function (i, s, o, g, r, a, m) {
...
 })(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
Run Code Online (Sandbox Code Playgroud)

通过替换每个命名参数:i, s, o, g, r与其对应的值window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga'

需要注意的是am参数没有输入值和更像结果变量.

这大致相当于(不要担心变量范围等)

(function (i, s, o, g, r, a, m) {
     window['GoogleAnalyticsObject'] = 'ga';
     window['ga'] = window['ga'] || function () {
         (window['ga'].q = window['ga'].q || []).push(arguments)
     }, window['ga'].l = 1 * new Date();
     a = document.createElement('script'),
     m = document.getElementsByTagName('script')[0];
     a.async = 1;
     a.src = '//www.google-analytics.com/analytics.js';
     m.parentNode.insertBefore(a, m)
 })(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');

 ga('create', 'UA-xxxxxxxx-x', 'xxxxxx.com');
 ga('send', 'pageview');
Run Code Online (Sandbox Code Playgroud)

简而言之,这段代码的本质是它创建了一个带有该行的新脚本标记:

a = document.createElement('script'),
Run Code Online (Sandbox Code Playgroud)

然后找到第一个脚本标记

m = document.getElementsByTagName('script')[0];
Run Code Online (Sandbox Code Playgroud)

然后它将新创建的脚本标记设置为异步执行(如果需要,可以通过了解Layman术语中的异步代码获得有关异步执行的更多信息)

a.async = 1;
Run Code Online (Sandbox Code Playgroud)

上面的1中的1相当于true,它只是因为它更短而使用1.

之后,设置此脚本标记的src

 a.src = '//www.google-analytics.com/analytics.js';
Run Code Online (Sandbox Code Playgroud)

请注意,上面没有在URL中指定协议(http或https).这将允许脚本加载到当前的浏览器协议中.

最后它插入到第一个脚本标记之前,因此浏览器可以开始加载它.

 m.parentNode.insertBefore(a, m)
Run Code Online (Sandbox Code Playgroud)

因此,要总结:

  1. 我们创建一个脚本标记
  2. 我们将其设置为异步加载 async=true
  3. 我们在文档中的第一个脚本标记之前插入此脚本标记

与谷歌分析相关的细节.

 window['ga'] = window['ga'] || function () {
     (window['ga'].q = window['ga'].q || []).push(arguments)
 }, window['ga'].l = 1 * new Date();
Run Code Online (Sandbox Code Playgroud)

定义名为的全局函数ga,将其参数推送到队列中的数组(命名q)

然后用线条

 ga('create', 'UA-xxxxxxxx-x', 'xxxxxx.com');
 ga('send', 'pageview');
Run Code Online (Sandbox Code Playgroud)

它将这些"事件"推送到队列数组中.

当脚本加载,它检查的值GoogleAnalyticsObject,它早些时候设置为指向的名称ga与线

 window['GoogleAnalyticsObject'] = 'ga';
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助

  • 很好的答案@Zlatin。想知道您是否知道为什么这个脚本会动态生成一个 *new* 脚本标签?为什么不简单地使用 &lt;script ... async="true"&gt; 首先? (3认同)
  • 查看http://www.nczonline.net/blog/2009/07/28/the-best-way-to-load-external-javascript/和http://www.html5rocks.com/en/tutorials/speed/脚本加载/ - 它们可以让您深入了解为什么可能更喜欢使用基于脚本的其他脚本加载来加载纯脚本标记.另请查看http://stackoverflow.com/questions/8996852/load-and-execute-order-of-scripts (2认同)
  • 我真的希望 stackoverflow 上有更多这样的解释问题 (2认同)

bro*_*eib 27

Google已发布此代码的未缩小版本:

<!-- Google Analytics -->
<script>
/**
 * Creates a temporary global ga object and loads analytics.js.
 * Parameters o, a, and m are all used internally. They could have been
 * declared using 'var', instead they are declared as parameters to save
 * 4 bytes ('var ').
 *
 * @param {Window}        i The global context object.
 * @param {HTMLDocument}  s The DOM document object.
 * @param {string}        o Must be 'script'.
 * @param {string}        g Protocol relative URL of the analytics.js script.
 * @param {string}        r Global name of analytics object. Defaults to 'ga'.
 * @param {HTMLElement}   a Async script tag.
 * @param {HTMLElement}   m First script tag in document.
 */
(function(i, s, o, g, r, a, m){
  i['GoogleAnalyticsObject'] = r; // Acts as a pointer to support renaming.

  // Creates an initial ga() function.
  // The queued commands will be executed once analytics.js loads.
  i[r] = i[r] || function() {
    (i[r].q = i[r].q || []).push(arguments)
  },

  // Sets the time (as an integer) this tag was executed.
  // Used for timing hits.
  i[r].l = 1 * new Date();

  // Insert the script tag asynchronously.
  // Inserts above current tag to prevent blocking in addition to using the
  // async attribute.
  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');

// Creates a default tracker with automatic cookie domain configuration.
ga('create', 'UA-XXXXX-Y', 'auto');

// Sends a pageview hit from the tracker just created.
ga('send', 'pageview');
</script>
<!-- End Google Analytics -->
Run Code Online (Sandbox Code Playgroud)

https://developers.google.com/analytics/devguides/collection/analyticsjs/tracking-snippet-reference

Zlatin的逐行解释仍然有效.