Добавление script
узлов должно работать просто отлично.Поскольку эти сценарии будут выполняться асинхронно с кодом, добавляющим их, вам нужно будет дать им обратный вызов для вызова, чтобы сделать следующее по порядку.Например:
if (window.localStorage) {
// Load the local storage stuff; once loaded, it'll call
// `doTheNextThing`
var script = document.createElement('script');
script.type = "text/javascript";
script.src = /* ... the URL of the script ... */;
document.body.appendChild(script); // Or append it to `head`, doesn't matter
// and `document.body` is convenient
}
else {
// Skip loading it
setTimeout(doTheNextThing, 10);
}
function doTheNextThing() {
// ...
}
... где динамический скрипт, который вы загружаете для вызова вещи localStorage
doTheNextThing
после его загрузки - так что в случае, когда есть localStorage
, динамически загружаемыйскрипт вызывает doTheNextThing
, но в случае, если его нет, приведенный выше код делает.Обратите внимание, что я сделал вызов из приведенного выше кода асинхронно (через setTimeout
) специально: сделать его всегда асинхронным независимо от того, как он вызывается, уменьшит ваши шансы на отсутствие ошибок (например, добавив что-то, на что опираетсяон вызывается синхронно, а затем забывает проверить это незначительное изменение в IE).
Обновление : Выше указано, что вы контролируете загружаемый скрипт, но выуточнил, что это не так.В этом случае вам нужно загружать сценарии по одному и опрашивать предоставляемую ими функцию (обычно это свойство объекта window
, например window.jQuery
), что-то вроде этого (не проверено):
// Load the script designated by `src`, poll for the appearance
// of the symbol `name` on the `window` object. When it shows
// up, call `callback`. Timeout if the timeout is reached.
function loadAndWait(src, name, timeout, callback) {
var stop, script;
// Do nothing if the symbol is already defined
if (window[name]) {
setTimeout(function() {
callback("preexisting");
}, 10);
}
else {
// Load the script
script = document.createElement('script');
script.type = "text/javascript";
script.src = src;
document.body.appendChild(script);
// Remember when we should stop
stop = new Date().getTime() + timeout;
// Start polling, long-ish initial interval
setTimeout(poll, 150);
}
function poll() {
if (window[name]) {
// Got it
callback("loaded");
}
else if (new Date().getTime() > stop) {
// Time out
callback("timeout");
}
else {
// Keep waiting, shorter interval if desired
setTimeout(poll, 75);
}
}
}
... который вы будете использовать для загрузки jQuery следующим образом:
loadAndWait(
"http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js",
"jQuery",
10000, // ten seconds or whatever
function(result) {
// ...do the next one if result !== "timeout"
}
);
Вы можете либо вкладывать вызовы в loadAndWait
в каждом из обратных вызовов предыдущих вызовов,или используйте массив и счетчик:
loadThese(
[
{ src: "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js",
symbol: "jQuery"
},
{
src: "http://the-next-one",
symbol: "nextSymbol"
}
],
doTheNextThing
);
function loadThese(scripts, callback) {
var index = 0;
run("okay");
function run(result) {
var entry;
if (result === "timeout") {
callback(result);
}
else if (index < scripts.length) {
entry = scripts[index++];
loadAndWait(entry.src, entry.symbol, 10000, run);
}
else {
callback("loaded");
}
}
}
Там loadThese
устанавливает цикл, используя run
для загрузки каждого скрипта по очереди.
Все вышеперечисленное полностью отключеноthe-cuff и, вероятно, может быть затянута и пуленепробиваема, но вы поняли.
Не по теме , но мой вопрос: действительно ли так много кода, что это проблема?для браузеров, которые не могут использовать его для загрузки?Если размер файлов увеличится на много , вы фактически замедлите свой сайт для пользователей с продвинутыми браузерами, не получая при этом ничего от других.Ниже определенного размера затраты на подключение к серверу для получения сценария так же важны, как и его передача.Является ли дополнительный материал 50 КБ кода?Я бы сделал несколько тестов, чтобы проверить, действительно ли это необходимо ... Возможно, это (возможно, у вас уже есть!), Но стоит упомянуть ...
Обновление вне темы : В вашем обновленном вопросе вы перечислите пять отдельных скриптов, которые вы будете загружать, если поддерживается localStorage
.Даже если предположить, что вы получаете все пять из различных CDN, это много индивидуальных запросов сценариев (независимо от того, были ли они выполнены обычным способом или как описано выше), каждый из которых имеет для обработки по одному за раз.Это проблема с загрузкой страницы, ожидающая своего появления.Несмотря на (возможно) потерю преимуществ CDN и существующего кэширования, вы можете посмотреть на то, как захватить все эти сценарии, объединить их и разместить объединенную версию в одном файле.См. «Минимизация HTTP-запросов» в «1045 * правилах производительности YUI» (я предпочитаю термин «руководство», но неважно).Это также упростит вашу динамическую загрузку.