我最近在SharePoint Webparts(2010)中使用LABjs
来加载脚本。这样做的主要原因是为了避免在同一页上添加多个Webparts时重复加载同一个库(例如jquery
和jquery.ui
)。这样每个Webpart都可以单独指定其依赖项,而不需要监控其他已添加或可能添加的Webpart。
LABjs
和另一个包含脚本链的文件通过<script>
标签在Webpart标记底部加载。
大多数情况下,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()
实例化它,并将我的DOM相关代码封装在其中。
(function ($) {
...
})(core.$);
并将 .script(".../js/core.js")
的调用移动到链的末尾(以确保所有插件都正确回滚)。
虽然这没有解决问题,但出现次数已经降至大约50分之1。
<script>
标签同步加载库不会导致错误。 - LdTriggerjQuery
调用应该确保脚本内容绑定到 DOM 就绪事件。 - LdTrigger