Загружать javascript последовательно из кода javascript

У меня есть виджет javascript, который включается на страницу путем вставки одного тега script (поскольку приложение должно быть легко распространяемым):

<script type="text/javascript" src="loadMyWidget.js"></script>

Затем loadMyWidget.js необходимо загрузить несколько файлов сценариев, которые должны выполняться в определенной последовательности. Я пытался загрузить их асинхронно, вставляя элементы сценария в DOM, но это не дает мне контроля над последовательностью.

Я также пытался использовать head.js, который отлично подходит для современных браузеров, но я не могу заставить его работать в IE7 и 8.

Сокращение скриптов в один файл, к сожалению, затруднено, так как он состоит из нескольких файлов из разных проектов, и я не знаю, когда обновлять скрипт.

Как бы просто это ни казалось, мне нужно загрузить файлы javascript из кода javascript в определенной последовательности и заставить его работать во всех браузерах, включая IE7 и 8.


person Jørgen    schedule 31.05.2012    source источник
comment
Пробовали ли вы использовать RequireJS?   -  person lanzz    schedule 31.05.2012
comment
Я рассматривал RequireJS, но надеялся на более простое решение.   -  person Jørgen    schedule 31.05.2012
comment
Вы используете jQuery? В этом случае вы можете попробовать вложить $.getScript().   -  person David Hellsing    schedule 31.05.2012
comment
Я пытаюсь загрузить jQuery, так что это мне мало поможет :P Но спасибо.   -  person Jørgen    schedule 31.05.2012
comment
Вы можете объединить jquery с yourloadMyWidget.js. Это позволит вам иметь ваши зависимости в вашем основном файле js.   -  person Thinking Sites    schedule 31.05.2012
comment
Какова конечная цель здесь? Вы пытаетесь иметь только один вызов сценария и заставить этот единственный сценарий загружать другие сценарии? Или есть какая-то другая причина асинхронной загрузки?   -  person Thinking Sites    schedule 31.05.2012
comment
Смотрите мою правку. Мне нужно, чтобы приложение было легко распространяемым, и оно дополнительно состоит из файлов из нескольких проектов.   -  person Jørgen    schedule 31.05.2012
comment
Один сценарий, чтобы управлять ими всеми...   -  person canon    schedule 31.05.2012


Ответы (5)


Я столкнулся с этой же проблемой и решил ее с помощью:

document.write('<script type="text/javascript" src="other1.js"></script>');
document.write('<script type="text/javascript" src="other2.js"></script>');

runSomeCode();

Код будет загружен и запущен синхронно. Плюсы: простой, легкий, кроссбраузерный, без зависимостей. Минусы: некрасиво.

Подробнее: https://stackoverflow.com/a/3292763/235179

person Josh Johnson    schedule 31.05.2012
comment
Я знаю, что Вы имеете ввиду. Рад помочь. - person Josh Johnson; 31.05.2012
comment
Если я не правильно понял, это перезаписывает весь документ. Таким образом, все, что было ранее создано в DOM, теряется. - person Neptilo; 25.12.2014
comment
@Neptilo: ты не правильно понял. Ничего не потеряно. document.write() добавляет к существующему документу. - person recursive; 08.09.2016
comment
Это было так давно. Я не помню, почему я думал, что это перезапишет весь документ. Оглядываясь назад на свой проект, я думаю, что решил проблему, не выполняя никакого кода во включенных сценариях, а только объявляя классы и функции, а затем вызывая только основную функцию из одного из этих сценариев. - person Neptilo; 09.09.2016

Если вы используете jQuery.getScript(), вы можете использовать его как $.when(), чтобы отложить выполнение до тех пор, пока все не перестанет загружаться.

Если под «последовательным выполнением» вы подразумеваете, что вам нужно загрузить реквизиты перед выполнением, будет работать следующее

$(function(){
   $.when(
      $.getScript("/script1"),
      $.getScript("/scirpt2"),
      $.getScript("/script3")
}).done(function(){
    // do stuff with the contents of my new script files
});

Если под последовательным выполнением вы подразумеваете, что вам нужно выполнять файлы один за другим, попробуйте следующее:

$.Deferred()
.then(function () { return $.getScript("/script1"); })
.then(function () { return $.getScript("/scirpt2"); })
.then(function () { return $.getScript("/script3"); })
.resolve();

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

Рекомендуемое чтение

person Thinking Sites    schedule 31.05.2012
comment
Это не гарантирует последовательного порядка выполнения, не так ли? - person David Hellsing; 31.05.2012
comment
Нет, я полагаю, что нет. Я немного по другому понял при первом прочтении. Работа над редакцией... - person Thinking Sites; 31.05.2012
comment
Похоже на достойное решение, если вы используете jquery, то есть :) +1 - person Jørgen; 31.05.2012
comment
Признаюсь, jquery меня избаловал. Я ничего не делаю без него. - person Thinking Sites; 31.05.2012

Если вам нужен ванильный JS, что-то вроде этого может работать:

function loadScripts(scripts, complete) {
    var loadScript = function( src ) {
        var xmlhttp, next;
        if (window.XMLHttpRequest)  {
            xmlhttp = new XMLHttpRequest();
        } else {
            try {
                 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
            } catch(e) {
                return;
            }
        }
        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                eval(xmlhttp.responseText);
                next = scripts.shift();
                if ( next ) {
                    loadScript(next);
                } else if ( typeof complete == 'function' ) {
                    complete();
                }
            }
        }
        xmlhttp.open("GET", src , true);
        xmlhttp.send();
    };

    loadScript( scripts.shift() );
}

loadScripts(['jquery.js','jquery.plugin.js'], function() {
    console.log('loaded');
});

Протестировано в Chrome, должно работать и в IE.

person David Hellsing    schedule 31.05.2012
comment
Это выглядит великолепно. Я полагаю, что именно так работает большинство фреймворков AMD. Однако я не могу заставить его работать в IE, и поведение очень похоже на мою попытку с head.js. - person Jørgen; 31.05.2012
comment
Что не работает в IE? (обновляю VMware, проверю через минуту). - person David Hellsing; 31.05.2012
comment
Только что попробовал его в своем IE9 с инструментами разработки для версий IE7-8, и он прошел мои тесты. С какой версией IE у вас проблемы? - person David Hellsing; 31.05.2012
comment
Я также использую инструменты разработчика IE9. Я получаю сообщение об ошибке неопределенной переменной, поэтому я предполагаю, что это что-то из последовательности. У меня это работает с document.write, хотя я ненавижу это решение. - person Jørgen; 31.05.2012

Вы пробовали require.js? http://requirejs.org/

person Someth Victory    schedule 31.05.2012

person    schedule
comment
Если не удалось загрузить один скрипт, все последующие скрипты не будут загружены. - person Thinh Vu; 23.12.2016