【发布时间】:2015-09-01 15:26:31
【问题描述】:
我最近改用 LABjs 在 SharePoint Webparts (2010) 中加载脚本。这样做的主要原因是为了避免在同一页面中添加多个 Webpart 时多次将相同的库(如 jquery 和 jquery.ui)加载到页面中。这样,它们中的每一个都可以单独指定其依赖项,而无需监管哪些其他 Webpart 已经或可能被添加。
LABjs 和另一个包含脚本链的文件都是通过 Webpart 标记底部的 <script> 标记加载的。
10 次中有 9 次,Javascript 执行没有任何问题。但每隔一段时间,就会抛出一个异常,声明为TypeError: $(...).button is not a function。
即使页面上只有一个 Webpart 并且似乎独立于浏览器,也会发生这种情况(在 FireFox 38、Chrome 43 和 IE 11/IE 8 中测试,由页面强制)。
链看起来像这样(为清楚起见进行了编辑):
$LAB.setOptions({Debug:true})
.script("../js/jquery-1.11.3.min.js").wait()
.script("../js/jquery-migrate-1.2.1.min.js").wait()
.script("../js/jquery-ui.min.js").wait()
.script("../js/core.js")
.wait(function(){
jQuery(function() {
init(); // The jQuery UI .button() call
});
})
.script("../js/jquery.multiselect.min.js").wait()
.script("../js/jquery.multiselect.filter.min.js")
.script("../js/rte/jquery.rte.js").wait()
.script("../js/rte/jquery.rte.tb.js")
.script("../js/rte/jquery.ocupload-1.1.4.js")
.wait(function () {
jQuery(function() {
// Some DOM-dependant code lives here
});
});
这是调试器输出的内容(为清楚起见也进行了编辑):
start script load (ordered async): ../js/jquery-1.11.3.min.js
start script load (ordered async): ../js/jquery-migrate-1.2.1.min.js
start script load (ordered async): ../js/jquery-ui.min.js
start script load (ordered async): ../js/core.js
start script load (ordered async): ../js/jquery.multiselect.min.js
start script load (ordered async): ../js/jquery.multiselect.filter.min.js
start script load (ordered async): ../js/rte/jquery.rte.js
start script load (ordered async): ../js/rte/jquery.rte.tb.js
start script load (ordered async): ../js/rte/jquery.ocupload-1.1.4.js
script execution finished: ../js/jquery-1.11.3.min.js
script execution finished: ../js/jquery-migrate-1.2.1.min.js
script execution finished: ../js/jquery-ui.min.js
script execution finished: ../js/core.js
$LAB.wait() executing: function (){ jQuery(function() { init(); }); }
$LAB.wait() error caught: TypeError: $(...).button is not a function
...
script execution finished: ../js/jquery.multiselect.min.js
script execution finished: ../js/jquery.multiselect.filter.min.js
script execution finished: ../js/rte/jquery.rte.js
script execution finished: ../js/rte/jquery.rte.tb.js
script execution finished: ../js/rte/jquery.ocupload-1.1.4.js
$LAB.wait() executing: function () {
jQuery(function() {
...
});
}
$LAB.wait() error caught: TypeError: $(...).multiselect is not a function
...
此错误几乎总是伴随着jquery.ui 库的较长加载时间。
然而,与此同时,从调试器的输出中可以清楚地看出,它在.button() 调用之前已经完成了执行。
我已经与这个问题斗争了一段时间,如果对问题可能是什么以及如何解决它提供任何帮助/见解,我将不胜感激。我一直在爬取 LABjs 文档,以寻找我可能做错了什么的线索,但似乎什么都没有出现在我身上。
注意:
标题中确实存在对jquery 的<script> 引用,但是无法删除此引用(我无权访问母版页),并且我已经尝试从链中删除jquery,但无济于事。
编辑:
有人建议该问题可能是由于 SharePoint 服务器位于负载平衡器之后,这可能是导致 jquery.ui 库加载时间异常长的原因。虽然这是一种可能性,但我不明白这会如何或为什么会影响 LABjs 的加载/执行功能。
---
更新
经过一番挖掘,我发现,由于某种我仍然不知道的原因,jquery.ui 库绑定到 jquery 而不是 $,正如我的代码所期望的那样。为了尝试解决这个问题,我在 core.js 中创建了一个变量 core.$,它用 jQuery.noConflict() 实例化,并用
(function ($) {
...
})(core.$);
并将.script(".../js/core.js") 调用移到链的末尾(以确保所有插件都正确回滚。)
虽然这并没有解决问题,但出现次数已经下降到大约 50 分之一。
【问题讨论】:
-
如果 Sharepoint 是负载平衡的 - 确保所有 js 文件(尤其是 jquery-ui)都存在于所有服务器上。
-
我已经在单独指向每个服务器(而不是负载平衡器)时对其进行了测试,并且所有文件都正确加载。此外,当不指向负载平衡器时,似乎不会发生错误。
-
我还应该提到该错误仅发生在开发服务器上。生产服务器(也是负载平衡的)工作正常。
-
不使用 LABjs 是否每次都有效?
-
视情况而定。如果页面上只有一个这样的 webpart,那么,简单地使用
<script>标签同步加载库不会导致错误。
标签: javascript jquery jquery-ui sharepoint-2010 labjs