IO v6. Отложенная загрузка скриптов. Работа с Yepnope
Отложенная загрузка скриптов происходит через библиотеку уepnope и служит для ускорения отображения html страницы. Теперь для того, чтобы страница отобразилась, не требуется подгрузка всех скриптов. Необходимые скрипты подгружаются до отображения, а все остальные после.
Ниже приведен код загрузки кабинета. Сначала подгружаются необходимые css, затем js: bootstrap css, уepnope, io.base.js, jquery.
Tinymce подгружается только из-за того, что он не работает через уepnope.
Далее подгрузка осуществляется через плагин уepnope следующих модулей: jquery-ui, bootstrap js, liveready, io.js, jquery.migrate. В принципе, список может быть длинным.
$.holdReady(true) говорит jquery, чтобы он задержал обработчик $(document).ready. Он сработает после того, как выполнится команда $.holdReady(false). Все команды, которые используют скрипты bootstrap, jquery-ui должны обрабатываться в $(document).ready, иначе произойдет ошибка javascript, т.к. скрипт еще не подгрузился.
Важной особенностью является команда ioGetModuleUrls({module: 'jquery-ui', push: 1}). Она возвращает ссылки js и css, которые необходимо подгрузить для работы модуля jquey-ui. Причем после срабатывания этой функции, данные заносятся в кеш, и повторно не возвращаются. Это нужно для того, чтобы уepnope не грузил дважды один и тот же скрипт.
<script>
$.holdReady(true);
var load = [];
//load = load.concat(ioGetModuleUrls({module: 'jquery-ui', push: 1}));
//load = load.concat(ioGetModuleUrls({module: 'jquery-ui-flick', push: 1}));
load = load.concat(ioGetModuleUrls({module: 'bootstrap', version: 3, push: 1}));
load = load.concat(ioGetModuleUrls({module: 'liveready', push: 1}));
load = load.concat(['/files/modules/io.js?_=15']);
load = load.concat(['/files/modules/jquery/jquery-migrate-1.2.1.min.js']);
load = load.concat(ioGetModuleUrls({module: 'jquery-blockUI', push: 1}));
load = load.concat(ioGetModuleUrls({module: 'the-modal', push: 1}));
yepnope({
load: load,
complete: function(){
jsApplication.busyEnabled = true;
jsApplication.openAjaxEnabled = true;
ioInit({
'user.id': '{{user.id}}',
'user.login': '{{user.login}}',
'user.account': '{{user.account}}',
currentlang: 'def',
});
$.blockUI.defaults.theme = true;
$.holdReady(false);
if(jsApplication.__busy <= 0){
$('#loadBusy').css('display', 'none');
$('body').removeClass('scroll-lock');
}
//jsApplication.busy(true);
}
});
$(document).ready(function(){
});
</script>
Загрузка скриптов в диалоговых окнах
Очень часто встречается задача, что диалоговое окно использует свой скрипт, который редко встречается в проекте, например jquerytree. Его не желательно каждый раз грузить при генерации страницы. В этом случае так же используется уepnope.
В ниже приведенном коде подгружаются модули noty, noty-topRight, jquey-contextmenu, jquery-dynatree, chosen. Если модули ранее не загружались, то срабатывает функция onChoosenSelect(), которая инициирует работу с chosen (список функций можно посмотреть в io.js), а также срабатывает функция dynatreeDo().dynatreeDo – это пользовательская функция, которая должна инициировать работу с деревом. Обычно функции, инициирующие работу, пишутся в $(document).ready, но т.к. мы имеем дело диалоговым окном, $(document).ready не сработает. Если диалоговое окно подгружалось несколько раз, то естественно load будет пустой и скрипты второй раз грузиться не будут, поэтому просто выполнится функция dynatreeDo и инициирует работу с деревом.
Причина, по которой написан setTimeout следующая: обычно подгрузка пишется в самом верху, а функция описана ниже.
ВАЖНО
В скрипте написаны функции onBootstrapEditable(), и т.д. (все функции можно посмотреть в io.js). Это нужно для того, чтобы bootstrap-editable сработал после того, как будет загружен. Точнее, сработает функция liveready для всех элементов, где объявлен bootstrap.
Функция jsApplication.pageLoad это замена $(document).ready, и ее следует использовать вместо $(document).ready.
<script>
{% set ID = random(999999) %}
jsApplication.pageLoad(function(){
{% set variable = 'var_'~random(999999)%}
var {{variable}} = 0;
var param = '';
var load = [];
load = load.concat(ioGetModuleUrls({module: 'nicetable', push: 1}));
load = load.concat(ioGetModuleUrls({module: 'bootstrap-editable', version: '1.5.1-3', push: 1}));
if(jsApplication.busy && load.length > 0){
jsApplication.busy(true);
{{variable}} = 1;
}
if(load.length > 0){
yepnope({
load: load,
complete: function(){
if(jsApplication.busy && {{variable}}) jsApplication.busy(false);
onBootstrapEditable();
setTimeout('onLoad{{ID}}()', 10);
},
});
} else {
if(jsApplication.busy && {{variable}}) jsApplication.busy(false);
setTimeout('onLoad{{ID}}()', 10);
}
});
function onLoad{{ID}}(){
// здесь пишется код, который должен выполниться, когда страница и все скрипты прогрузятся
}
</script>