2013-10-04 38 views
0

我正在加载一个我异步创建的脚本以帮助防止减慢网站速度。我无法致电Class.track({“some_param”:“some_data”}),因为它尚未可用。我如何实现异步加载并能够调用该类?异步脚本不可访问

在js中加载的代码如下,它发生在关闭body标签之前,并且Class.track在它下面被调用。

<script type="text/javascript"> 

    (function() { 
     function async_load(){ 
      var api_id = "XXXXXXXXX"; 
      var s = document.createElement('script'); 
      s.type = 'text/javascript'; 
      s.async = true; 
      s.src = 'https://site.com/script.js?id=' + api_id; 
      var x = document.getElementsByTagName('script')[0]; 
      x.parentNode.insertBefore(s, x); 
     } 
    if (window.attachEvent) 
     window.attachEvent('onload', async_load); 
    else 
     window.addEventListener('load', async_load, false); 
    })(); 

    Class.track("page_view", {"page":"plans"}); 
</script> 

编辑

接过从丹和注释的答案从TJ,决定修改它,下面就是我想出了,希望这会帮助别人。

<script type="text/javascript"> 
    var _Class = new function(){ 
     var items = []; 

     this.track = function(type, params){ 
      params = params || {}; 
      items.push({"type":type, "params":params}); 
     } 

     this.get = function(){ 
      return items; 
     } 

    }; 

    var Class = _Class; 

    (function() { 
     function async_load(){ 
      var api_id = "XXXXXXXXX"; 
      var s = document.createElement('script'); 
      s.type = 'text/javascript'; 
      s.async = true; 
      s.src = 'https://site.com/script.js?id=' + api_id; 
      s.onload = function(){ 
       var items = _Class.get(); 
       Class.trackBatch(items); 
      }; 
      var x = document.getElementsByTagName('script')[0]; 
      x.parentNode.insertBefore(s, x); 
     } 
    if (window.attachEvent) 
     window.attachEvent('onload', async_load); 
    else 
     window.addEventListener('load', async_load, false); 
    })(); 

    Class.track("page_view", {"page":"plans"}); 
</script> 
+1

,你可以做一个假Class.track它记录来电,直到真正的显示出来,只要确保重挫window.Class之前抢电话......就个人而言,我更喜欢轮询自动执行的功能会返回一个setTimeout(arguments.callee);如果self.Class是falsy ... – dandavis

+0

@dandavis谢谢,我实际上使用你说的话+ TJ的答案是什么。而不是使用setTimeout,我正在使用onload。很酷的东西! –

回答

2

在所有当前主要的浏览器,script元素的onload可用于:

s.onload = function() { 
    /* ...this is called when the script is loaded, so `Class` should 
     be available... 
    */ 
    Class.track("page_view", {"page":"plans"}); 
}; 

在旧版本的IE,你不得不使用onreadystatechange代替,并检查元素的readyState属性是字符串"complete"

或者,当然,你可以使用setTimeoutsetInterval轮询全局符号(Class,你的情况,我怀疑)创建(通过typeof,例如if (typeof Class === "undefined") { /* ...schedule another check in a few milliseconds... */ })。

+0

感谢您的支持,如果我加载脚本,并尝试在整个页面的任何位置调用Class.track(),这是否是最好的路线? –

+0

@BrianPutt:我不太清楚你的意思。使用'onload'(在旧IE上使用'onreadystatechange')是知道脚本何时加载的最佳方式。轮询也是一种选择,但往往涉及更多的滞后时间。 –

+0

试图复制如何谷歌分析工作的,你在GA代码加载,然后你可以使用ga.track()在整个页面的任何地方,希望这是有道理的,因为我相当新的JS世界 –