2014-02-05 2 views
0

Я создал небольшую функцию загрузчика скриптов, которая будет перебирать объект javascript, заполненный именами файлов в каталоге. Это используется для динамической загрузки шаблонов Mustache для создания страницы.

Я создал объект javascript, чтобы отобразить шаблоны в том порядке, в котором я хочу, чтобы они выводились на страницу, но иногда, когда я загружаю страницу, элементы не в правильном порядке. Я знаю, что теоретически, что $ .each() «делает» итерацию по порядку сверху вниз, но мне интересно, есть ли способ, который я могу явно заставить сделать, чтобы избежать случайной неправильной страницы.

var loadModules = function(){ 
var templates = { 
    1 : 'header', 
    2 : 'about' 
} 
$.each(templates, function(key, value) { 
    $.getScript("js/modules/"+value+".js", function(){ 
     Init(); 
    }); 
}); 
} 

Это фрагмент кода и время от времени, когда я загружаю страницу вы увидите «о» секции появляются над «головой». Есть ли способ остановить это, или это просто «икота браузера»?

Я создал объект «шаблоны», чтобы указать порядок элементов страницы, но он, похоже, работает большую часть времени.

+1

объекты представляют собой неупорядоченный набор элементов. Сказано, что вы можете использовать ключ свойства для объекта и для целевого конкретного объекта. –

+1

. Ваш шаблон может быть массивом, который будет в порядке $ .each использует индексированный для перемещения массивов. –

+0

Отлично, я думаю, иногда самые простые методы являются лучшими. Взяв из обоих ваших ответов, я сменил объект на массив и заменил $ .each на простой цикл ol 'for, и он отлично работает. – nate63

ответ

1

Обновление, если вы не хотите изменять структуру шаблонов, чтобы они могли загружаться лучше асинхронно, тогда вам, возможно, придется отказаться от рекурсивного подхода загрузки. Это будет относительно сродни синхронной загрузке ресурсов, так как вы будете обеспечивать одновременный запуск только одного запроса.

var templates = [ 
    'header', 
    'about' 
    /*....*/ 
]; 

//load up your templates 1 by 1 in a recursive loop 
(function loadNextTemplate(index) { 
    if(index >= templates.length) return; //base case 
    $.getScript("js/modules/" + templates[index] + ".js") 
    .then(function() { 
     Init(); 
     loadNextTemplate(index + 1); 
    }); 
})(0); 
+0

Мне нравится внешний вид этого, но моя проблема в том, что каждый скрипт имеет собственную функцию Init(), и каждый Init() должен запускаться. Если я запустил Init только один раз, он загрузит только один из модулей. Как мне изменить это, чтобы запускать каждую функцию Init() загруженного сценария по мере ее загрузки? – nate63

+0

Итак, каждая из них выставляет другую глобальную функцию Init? – megawac

+0

в высшей степени, да. каждый из этих загруженных скриптов имеет собственную функцию Init() для инициализации модуля. – nate63

0

Затем вы звоните $.getScript, он отправляет XMLHttpRequest, которые используют как async по умолчанию в $.ajax. $.getScript - это короткий вызов $.ajax для файлов javascript. Таким образом, запускается each, он отправляет 2 асинхронных запроса AJAX без гарантии, в каком порядке заканчиваются запросы.

Если вы, как назвать Init после 2 запросов Ajax заканчивается, используйте jQuery Deffered/Promisespattern:

$.when($.getScript("js/modules/header.js"), $.getScript("js/modules/about.js")).done(function(){ 
    Init();//Init will call after to AJAX requests ends, but without its order 
}); 

Если вам нужно загрузить header.js всегда первым и about.js должен быть второй, использовать этот шаблон, как это:

$.when($.getScript("js/modules/header.js").then($.getScript("js/modules/about.js")).done(function(){ 
    Init();//header loads, after this about loads, after this Init will call 
}); 

Если вам нужно загрузить 10-15 js файлов, попробуйте использовать AMD по requirejs. Для этого нужны некоторые специальные функции обертки кода, но requirejs более полезен. Что касается меня с использованием Deffered/Promises для 15 обратных вызовов, это не ад.

+0

Я вижу, что вы говорите об асинхронном характере $ .getScript, но массив будет продолжать расти по мере добавления большего количества элементов на страницу, и мне было бы неловко связывать 10-15 слов «далее», чтобы обеспечить правильный порядок. Это уберет от полудинамического характера функции. – nate63

+1

Редактировать мой ответ. – Pinal

+0

Может быть, RequireJs - мой лучший вариант здесь ... Я проверю это. Спасибо – nate63

0

Решено. Вместо использования всегда асинхронный $ .getScript Я решил пойти с заходящим значением вызова async к false простого AJAX вызова. Это всегда загружает скрипты в том порядке, в котором они перечислены в массиве благодаря for loop и async:false Значение вызова ajax. Например:

var loadModules = function(){ 
//List modules in templates array in order you want them to appear in the DOM 
var templates = [ 
    'header', 
    'about' 
]; 


var i; 
for (i=0; i<templates.length; ++i){ 
    $.ajax({ 
     url: "js/modules/"+templates[i]+".js", 
     dataType: 'script', 
     success: function(){ 
      Init(); 
     }, 
     async: false 
    }); 
} 

Thaks за вашу помощь по этому вопросу. Я взял немного от каждого ответа/предложения и применил их все, поэтому я не знаю, кто отвечает, чтобы отметить как правильный.

+0

Примечание: установка ** async: false ** будет блокировать поток до тех пор, пока запрос не завершится. Рассмотрим случай, когда кто-то с плохим подключением к Интернету пытается загрузить контент - его браузер будет заморожен. См. Http://stackoverflow.com/questions/6517403/what-are-the-drawbacks-of-using-synchronous-ajax-call – megawac

+0

Вот сообщение, которое я искал по теме [Как вернуть ответ ajax call] (http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call/14220323#14220323) – megawac

+0

интересное чтение ... Моя проблема до тех пор, пока вызовы асинхронны, тогда первая возвращенная часть данных будет в верхней части страницы (моя страница полностью построена из загрузки этих модулей). Если это произойдет асинхронно, это будет хорошей идеей, тогда все модули будут загружаться в браузер одновременно, а порядок их на странице будет определяться самым быстрым ответом до самого медленного. Вот почему я экспериментировал с асинхронным: false param. Это может быть не идеальным, но, по крайней мере, я могу указать порядок элементов страницы. – nate63

Смежные вопросы