Ready 事件不一定 ready
使用 easyloader 的时候,必须要注意到脚本的加载时机问题,easyloader 会异步加载模块,所以,你使用的模块不一定已经加载了。比如下面的代码。
<script type="text/javascript"> easyloader.locale = "zh_CN"; using("messager", function () { alert("加载成功!"); }); $(function () { $.messager.alert('Warning', 'The warning message'); }); </script>
看起来非常简单,还使用了 jQuery 的 ready 函数。不幸的是,执行一下,就会发现如下的错误。
TypeError: $.messager is undefined
[在此错误处中断]
$.messager.alert('Warning', 'The warning message');
明明已经在前面使用 using 加载了,为什么还会出现这个错误呢?这不是已经在 ready 函数中使用了吗?
如果把前面的代码修改一下,使用 console.info 输入日志信息,就会很清楚了。
<script type="text/javascript"> easyloader.locale = "zh_CN"; using("messager", function () { console.info("加载 messager 成功。"); }); $(function () { console.info("Ready"); $.messager.alert('Warning', 'The warning message'); }); </script>
在 Firebug 中可以看到输出的信息。
很清楚,Ready 函数先于 using 函数执行了。
也就是说,你不能认为在 jQuery 的 Ready 函数中,已经加载了需要的模块。原因很简单,异步加载导致。
用 JavaScript 创建一个 script 元素,然后插入到 DOM 中,这样就实现了非阻塞的加载 javascript 脚本。此方法被称为 "Script DOM Element" 法。easyui的 easyloader 就是使用这种方式实现异步加载的。
那么,我们什么时候才能调用延迟加载的模块呢?答案是在加载模块的回调函数中,你可以将前面的代码修改为如下所示:
<script type="text/javascript"> easyloader.locale = "zh_CN"; using("messager", function () { console.info("加载 messager 成功。"); $.messager.alert('Warning', 'The warning message'); }); $(function () { console.info("Ready"); }); </script>
结论就是,如果你需要使用 easyui 的模块,就必须将使用代码放在模块的加载完成回调函数中,来保证模块正确完成加载工作。如果不涉及到 easyui ,那么就可以直接使用 jQuery 的 ready 函数。
不能使用 ready 函数了吗?
如果是在某个按钮的点击事件中调用 easyui 的模块呢?比如说,在点击某个按钮之后,使用 messager 的 alert 弹出一个提示框,也必须写在这个回调函数中吗?
这倒不必,按钮的点击事件注册还可以与原来一样写在 jQuery 的 Ready 函数中,因为在注册的时候,并没有真正调用 easyui 的方法,而点击是在以后的事情,这个时间间隔已经足以加载完成了。
加载多个模块怎么办?
如果是需要加载多个模块之后,又应该怎么办呢?别忘了,using 加载模块还可以使用字符串数组的方式直接指定多个模块,在多个模块加载完成之后,调用我们的回调函数,比如,我们使用了 linkbutton ,同时还希望使用 messager,可以传递一个字符串的数组,将主要使用的模块表示为 ["linkbutton","messager"],那么就可以如下完成。
<script type="text/javascript"> easyloader.locale = "zh_CN"; using(["linkbutton","messager"], function () { console.info("加载 messager 成功。"); $("#btnAlert").linkbutton(); $.messager.alert('Warning', 'The warning message'); }); $(function () { console.info("Ready"); }); </script>
这样就保证了我们脚本的正确执行。
在网上看到有朋友 放弃使用easyloader,因为使用的时候出现加载错误,可能就是因为上面分析的原因。
延伸阅读: