Недавно я переключился на использование LABjs
для загрузки сценариев в SharePoint Webparts (2010). Основная причина этого заключалась в том, чтобы не загружать одну и ту же библиотеку (например, jquery
и jquery.ui
) на страницу более одного раза, если несколько веб-страниц были добавлены на одну страницу. Таким образом, каждый из них может определять свои зависимости индивидуально, без необходимости полиции, какие другие веб-сайты были или могут быть добавлены.
Оба LABjs
, а другой файл, содержащий цепочки script, загружаются с помощью тегов <script>
в нижней части разметки Webpart.
9 раз из 10, Javascript выполняется без каких-либо проблем. Время от времени, однако, выдается исключение, указывающее TypeError: $(...).button is not a function
.
Это происходит, даже если на странице есть только одна веб-часть и, похоже, независима от браузера (протестировано в 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
, чтобы понять, что я могу делать неправильно, но, похоже, что-то не появляется на мне.
Примечание:
В заголовке существует <script>
ссылка на jquery
, однако эта ссылка не может быть удалена (у меня нет доступа к главной странице), и я уже попытался удалить jquery
из цепочки, но безрезультатно.
Изменить:
Кто-то предположил, что проблема может быть связана с тем, что сервер SharePoint находится за балансировщиком нагрузки, что может быть причиной чрезвычайно длительного времени загрузки в библиотеке jquery.ui
. Хотя это возможно, я не вижу, как и почему это повлияло бы на функциональность LABjs
load/execute.
---
Update
После некоторого копания, я обнаружил, что по какой-то причине это все еще неизвестно мне, библиотека jquery.ui
была привязана к jquery
, а не $
по мере того, как ожидал мой код. Чтобы попытаться исправить это, в core.js я создал переменную core.$
, которая была создана с помощью jQuery.noConflict()
, завернула мой зависимый от DOM код с помощью
(function ($) {
...
})(core.$);
и переместил вызов .script(".../js/core.js")
в конец цепочки (чтобы убедиться, что все плагины были отброшены правильно.)
Пока это не устранило проблему, вхождения упали примерно на 1 из 50.