不调用JavaScript全局回调函数?

时间:2013-07-14 10:21:57

标签: javascript jquery html function javascript-objects

我正在与其他几个人一起构建一个小型网络应用程序。我想让其他开发人员定义一些在文档准备好时总是调用的函数。

我们的应用将以下脚本插入到每个页面的HTML正文中:

<script type="text/javascript">
  (function(){
    window.Utils = {
      funcs: {}
    };

    $(document).ready(function(){
      alert('Calling funcs...');

      var startFunc = Utils.funcs['start'];
      if (startFunc != undefined){
        startFunc();
      }

      var finishFunc = Utils.funcs['finish'];
      if (finishFunc != undefined){
        finishFunc();
      }
    });
  })();
</script>

然后,在单独的.js文件中,开发人员应该能够执行以下操作:

Utils.funcs['start'] = function(){
    alert('Starting...');
};

Utils.funcs['finish'] = function(){
    alert('Finishing...');
};

但这不起作用。这些函数从未被调用过?

jsFiddle链接:http://jsfiddle.net/XvQtF/

3 个答案:

答案 0 :(得分:3)

jsFiddle的(非常令人惊讶)默认是将您的代码放在window load处理程序中。 (您可以在左侧的顶部看到这个,第二个下拉框显示“onload”。)在ready触发很久之后,加载过程中发生非常。因此,在您尝试运行它们之后才会添加这些功能。

如果其他开发人员在您的元素定义Utils.funcs之后的script元素中将Utils中的函数放入load但不等待start事件,那就没关系:{{3 }}


但是,对于它的价值,我倾向于使用pub / sub解决方案而不是单个函数。例如,如果您想拥有多个Deferred函数,那么您当前的结构将不允许它。

jQuery现在有Promise<!DOCTYPE html> <html> <head> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script> <meta charset=utf-8 /> <title>Pub/Sub with Deferred and Promise</title> </head> <body> <script> (function($) { // Deferred objects for our app states var start = new $.Deferred(), finish = new $.Deferred(); window.Utils = { start: start.promise(), // Only expose the Promise of each finish: finish.promise() // " " " " " " }; $(function() { alert("Calling funcs..."); // Start the app start.resolve(); // Finish the app (or whatever) finish.resolve(); }); })(jQuery); </script> <script> // Module 1 Utils.start.then(function() { alert("Module 1 Started!"); }); Utils.finish.then(function() { alert("Module 1 Finished!"); }); </script> <script> // Module 2 Utils.start.then(function() { alert("Module 2 Started!"); }); Utils.finish.then(function() { alert("Module 2 Finished!"); }); </script> </body> </html> ,可用于此目的。这是一个简单的例子:Updated Fiddle | Live Copy

{{1}}

答案 1 :(得分:0)

在另一个脚本中设置Utils作为第一个加载。此外,无条件地执行此操作(不在任何回调等):

/* load as first script, sets up a global container-object for later use */
var Utils = {
  funcs: {}
}

请注意,可以在全局范围内定义全局变量。

/* other script */
(function(){
  function myFunc() { /*...*/ };

  // now store a reference in Utils
  Utils.funcs.start = myFunc;
})();

如其他答案中所述:请注意各种脚本/代码的加载和调用顺序:

$(document).ready实际上是大多数浏览器(但早期版本的IE)的“DOMContentLoaded”事件。当最初在头部中找到的所有内联资源都已加载并且存在主体的DOM结构时,“DOMContentLoaded”将触发。 由于这不包括任何注入的内容,因此可能会授予事件在任何模块化库(通过注入脚本标记加载模块)完全加载并存在之前触发事件。 (鉴于这些脚本只使用浏览器提供的少量网络插槽/插槽同时加载图像和其他内联资源,它们可能是您在整个加载过程中最后准备好的事情之一。)< / p>

答案 2 :(得分:0)

而不仅仅是使用

 startFunc() and 
 finishFunc() 

尝试使用此

 startFunc.apply(this, null) and 
 finishFunc.apply(this, null)

这将调用函数。

也确保

 Utils.funcs['start']
 Utils.funcs['finish'] 

在被调用之前被初始化。