如何在尚未加载的异步javascript中使用函数? (作为Google Analytics的ga功能)

时间:2016-04-25 13:06:23

标签: javascript asynchronous javascript-events

我开发了一个需要在页面中加载异步的库。我的脚本加载:

<script type="text/javascript">
  (function(w,d) {
    var po = d.createElement('script'); po.type = 'text/javascript'; po.async = true;
    po.src = 'my_function-sdk.js';
    var s = d.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
  })(window, document);
</script>

我想在下面使用该功能:

<script>
      my_function("test");
</script>

或点击:

<a href="#" onclick="my_function('other test');">test click</a>

文件my_function-sdk.js中的函数定义:

function my_function(param) {
  console.log("in correct function");
  console.log(param);
}

我希望console.log打印&#34;正确的功能&#34; 我的函数在文件my_function-sdk.js中的定义方式。

JSFiddle:https://jsfiddle.net/adrianogodoy/n7ahygoj/8/

编辑: 我想像谷歌分析一样,使用ga函数立即关注加载脚本或任何其他地方,而不会收到未定义的错误:

  <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-XXXXXXX-1', 'auto');
    ga('send', 'pageview');
</script>

7 个答案:

答案 0 :(得分:1)

您正在执行my_function,无论脚本是否已加载。您可以创建一个onload / onreadystatechange事件处理程序,它将在脚本加载后执行回调函数:

po.onload = po.onreadystatechange = function() { my_function("text") };

答案 1 :(得分:1)

<强>解决!

在加载脚本之前,临时函数需要对调用进行排队,直到真正的函数加载为止。

<script type="text/javascript">
  (function(w,d) {
    w['my_function'] = w['my_function'] || function() {
      (w['my_function'].q = w['my_function'].q || []).push(arguments)
    }
    var po = d.createElement('script'); po.type = 'text/javascript'; po.async = true;
    po.src = 'https://rawgit.com/Godoy/830e372b7aa73158d68633bd15acb781/raw/7aaf95e41b30ee72fc7504bdac3475bc66fbec31/my_function-sdk.js';
    var s = d.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
  })(window, document);
</script>

在数组属性.push(arguments)中使用q进行排队。

因此,在外部脚本(my_function-sdk.js文件)中,弹出队列并为队列中的每个元素调用实际函数:

(function () {
  // Pop the call queue...
  q = window['my_function'].q;
  while(a = q.pop()){
    my_real_function(a);
  }

  //copy the complete function under old that was stacking queue
  my_function = my_real_function;
})();

// real function that will execute things
function my_real_function(params) {
  console.log("execute real function on remote file");
  console.log(params);
}

https://jsfiddle.net/adrianogodoy/na67hqj0/

答案 2 :(得分:0)

Adriano,我相信这种代码不起作用,因为您在页面加载后尝试添加JS文件,因此浏览器不会加载js脚本的内容。尝试研究这个主题。

答案 3 :(得分:0)

Adriano,我举例说明了如何使用eval资源和作为对象的函数以简单的方式完成它。看看https://jsfiddle.net/MarcelKohls/ghzuszzf/

@feed_items

我不建议使用eval ,但距离您更近。

另外,正如我之前所说,只是在文档中包含js文件,就无法使用它上面的函数。 Google分析在lib上做了很多工作,将内容转换为工作函数。

无论如何,上面的示例可以向您展示一些东西。 祝你好运。

答案 4 :(得分:0)

以下是加载页面内容后如何加载JS的示例方法:https://jsfiddle.net/MarcelKohls/g9hssz9t/

<script type="text/javascript">
   function downloadJSAtOnload() {
   var element = document.createElement("script");
   element.src = "https://rawgit.com/Godoy/c8cba89030c44e163997ed675c7fc0cd/raw/d67b5788c35a039e554d58e4dd24e57b9e5d519c/my_function-sdk.js";
   document.body.appendChild(element);
 }
  if (window.addEventListener)
  window.addEventListener("load", downloadJSAtOnload, false);
  else if (window.attachEvent)
      window.attachEvent("onload", downloadJSAtOnload);
  else window.onload = downloadJSAtOnload;
</script>

// here the JS call for the function
setTimeout(function(){ my_function('text here'); }, 3000); 

我将setTimeout设置为模拟页面的延迟,但最好将此调用放在您包含的文件的末尾,而不是确保在加载包含的文件时完成调用100%

答案 5 :(得分:0)

这里使用jquery .getScript()

这是一种更简单的方法

https://jsfiddle.net/MarcelKohls/oom4w4j5/

$( document ).ready(function() {
  $.getScript( "external-lib.js", function( data, textStatus, jqxhr ) {
    my_function('test content after page loaded');
  });
});

答案 6 :(得分:-1)

你的函数声明没有得到参数,试试这个:

(function(w,d) {
  w.my_function=function(value) { console.log(value); };
  var po = d.createElement('script'); po.type = 'text/javascript'; po.async = true;
  po.src = 'https://rawgit.com/Godoy/c8cba89030c44e163997ed675c7fc0cd/raw/d67b5788c35a039e554d58e4dd24e57b9e5d519c/my_function-sdk.js';
  var s = d.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})(window, document);


my_function("test");