Последовательная загрузка внешнего JavaScript

#javascript #jquery

#javascript #jquery

Вопрос:

Я работаю над javascript, который последовательно загружает список других внешних javascript.

Код, который у меня есть до сих пор:

 function loadJavascript(url){
    var js = document.createElement("script");

    js.setAttribute("type", "text/javascript");
    js.setAttribute("src", url);

    if(typeof js!="undefined"){
        document.getElementsByTagName("head")[0].appendChild(js)
    }
}

loadJavascript("Jquery.js");
loadJavascript("second.js");
loadJavascript("third.js");
  

Проблема, с которой я столкнулся, заключается в том, что иногда другие файлы js загружаются до завершения загрузки файла Jquery. Это приводит к некоторым ошибкам.

Возможно ли сделать так, чтобы следующий файл JS запускался только после завершения загрузки предыдущего файла.

Заранее спасибо

Комментарии:

1. Вы могли бы проверить head.js , который делает именно это, и посмотрите, как они это реализовали. headjs.com

Ответ №1:

Конечно, есть, но для этого написаны целые библиотеки. Перестаньте изобретать велосипед и используйте то, что уже работает. Попробуйте yepnope.js или, если вы используете Modernizr, он уже доступен как Modernizr.load

Ответ №2:

 loadJavascript("Jquery.js");
$(function(){
    $.getScript('second.js', function(data, textStatus){
        $.getScript('third.js', function(data, textStatus){
            console.log("loaded");
        });
    });
}
  

Кроме того, рассмотрите возможность использования CDN Google или Microsoft для jQuery, это сэкономит вам пропускную способность, и, надеюсь, ваши посетители уже будут кэшировать его.

Комментарии:

1. да, но я также хочу second.js должны быть загружены до third.js инициируется

Ответ №3:

На самом деле, нет необходимости загружать jquery внутри функции js. Но если вы настаиваете, вы можете callback убедиться, что другие js загружаются после jquery.

Тем не менее, я рекомендую вам загружать jquery непосредственно перед </body> использованием $.getScript для загрузки других .js

Ответ №4:

Вы могли бы проверить, загружен ли jQuery, что не лучший способ сделать это, но если вам действительно нужно подождать, пока загрузится jQuery, прежде чем загружать другие скрипты, вот как я бы это сделал, проверив наличие $ :

 loadJavascript("Jquery.js");    

T=0;
CheckIfLoaded();

function CheckIfLoaded() {
    if (typeof $ == 'undefined') {
      if (T <= 3000) {
          alert("jQuery not loaded within 3 sec");
      } else {
          T=T 200;
          setTimeout(CheckIfLoaded, 200);
    } else {
       loadJavascript("second.js");
       loadJavascript("third.js");
    }
}
  

Ответ №5:

С технической точки зрения: у браузеров есть забавный способ решить, в каком порядке выполнять / оценивать динамически загружаемый JS, поэтому, испытав ту же боль и проверив множество сообщений, библиотек, плагинов и т. Д. Я придумал это решение, автономное, маленькое, не требующее jquery, Т. Е. дружественное и т. Д. Код подробно прокомментирован:

 lazyLoader = {
    load: function (scripts) {
        // The queue for the scripts to be loaded
        lazyLoader.queue = scripts;
        lazyLoader.pendingScripts = [];
        // There will always be a script in the document, at least this very same script... 
        // ...this script  will be used to identify available properties, thus assess correct way to proceed
        var firstScript = document.scripts[0];
        // We will loop thru the scripts on the queue
        for (i = 0; i < lazyLoader.queue.length;   i) {
            // Evaluates if the async property is used by the browser
            if ('async' in firstScript ) {
                // Since src has to be defined after onreadystate change for IE, we organize all "element" steps together... 
                var element = document.createElement("script");
                element.type = "text/javascript"
                //... two more line of code than necessary but we add order and clarity
                // Define async as false, thus the scripts order will be respected
                element.async = false;
                element.src = lazyLoader.queue[i];
                document.head.appendChild(element);
            }
            // Somebody who hates developers invented IE, so we deal with it as follows:
            // ... In IE<11 script objects (and other objects) have a property called readyState...
            // ... check the script object has said property (readyState) ... 
            // ... if true, Bingo! We have and IE! 
            else if (firstScript.readyState) {
                // How it works: IE will load the script even if not injected to the DOM...
                // ... we create an event listener, we then inject the scripts in sequential order
                // Create an script element
                var element = document.createElement("script");
                element.type = "text/javascript"
                // Add the scripts from the queue to the pending list in order
                lazyLoader.pendingScripts.push(element)
                // Set an event listener for the script element 
                element.onreadystatechange = function() {
                    var pending;
                    // When the next script on the pending list has loaded proceed
                    if (lazyLoader.pendingScripts[0].readyState == "loaded" || lazyLoader.pendingScripts[0].readyState == "complete" ) {
                            // Remove the script we just loaded from the pending list
                            pending = lazyLoader.pendingScripts.shift()
                            // Clear the listener
                            element.onreadystatechange = null;
                            // Inject the script to the DOM, we don't use appendChild as it might break on IE
                            firstScript.parentNode.insertBefore(pending, firstScript);
                    }
                }
                // Once we have set the listener we set the script object's src
                element.src = lazyLoader.queue[i];
            }
        }
    }
}
  

Конечно, вы также можете использовать уменьшенную версию:

 smallLoader={load:function(d){smallLoader.b=d;smallLoader.a=[];var b=document.scripts[0];for(i=0;i<smallLoader.b.length;  i)if("async"in b){var a=document.createElement("script");a.type="text/javascript";a.async=!1;a.src=smallLoader.b[i];document.head.appendChild(a)}else b.readyStateamp;amp;(a=document.createElement("script"),a.type="text/javascript",smallLoader.a.push(a),a.onreadystatechange=function(){var c;if("loaded"==smallLoader.a[0].readyState||"complete"==smallLoader.a[0].readyState)c=smallLoader.a.shift(),
a.onreadystatechange=null,b.parentNode.insertBefore(c,b)},a.src=smallLoader.b[i])}};