我正在与其他几个人一起构建一个小型网络应用程序。我想让其他开发人员定义一些在文档准备好时总是调用的函数。
我们的应用将以下脚本插入到每个页面的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/
答案 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']
在被调用之前被初始化。