2015-05-05 2 views
0

Я пытаюсь лениво (динамически) загружать файлы javascript на свою веб-страницу.Ошибка загрузки файлов javascript динамически

я использовал это:

http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml

function loadjscssfile(filename, filetype){ 
    if (filetype=="js"){ //if filename is a external JavaScript file 
     var fileref=document.createElement('script') 
     fileref.setAttribute("type","text/javascript") 
     fileref.setAttribute("src", filename) 
    } 
    else if (filetype=="css"){ //if filename is an external CSS file 
     var fileref=document.createElement("link") 
     fileref.setAttribute("rel", "stylesheet") 
     fileref.setAttribute("type", "text/css") 
     fileref.setAttribute("href", filename) 
    } 
    if (typeof fileref!="undefined") 
     document.getElementsByTagName("head")[0].appendChild(fileref) 
} 

loadjscssfile("myscript1.js", "js") //dynamically load and add this .js file 
loadjscssfile("myscript2.js", "js") //dynamically load and add this .js file 
loadjscssfile("myscript3.js", "js") //dynamically load and add this .js file 

эти 3 сценария должны быть загружены в последовательности.

myscript3 зависит от myscript2
и myscript2 зависит от myscript1.

пытается загрузить его таким образом ведет себя странно.

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

Я делаю что-то неправильно.


Обновлено:

Я использую этот код для загрузки файлов в правильной последовательности

function loadjscssfile(filename, filetype) { 
     if (filetype == "js") { //if filename is a external JavaScript file 
      var fileref = document.createElement('script') 
      fileref.setAttribute("type", "text/javascript") 
      fileref.setAttribute("src", filename) 
     } 
     else if (filetype == "css") { //if filename is an external CSS file 
      var fileref = document.createElement("link") 
      fileref.setAttribute("rel", "stylesheet") 
      fileref.setAttribute("type", "text/css") 
      fileref.setAttribute("href", filename) 
     } 
     return fileref; 
    } 

    function loadSync(files, types) { 
     if (typeof (files[0]) === 'undefined') return false; 
     var script = loadjscssfile(files[0], types[0]); 
     script.onload = function() { 
      files.shift(); 
      types.shift(); 
      loadSync(files, types); 
     } 
     if (typeof script != "undefined") 
      document.getElementsByTagName("head")[0].appendChild(script) 
    } 

    loadSync(['scripts/module3.base.js', 'scripts/module3.core.js', 'scripts/module3.init.js'], ['js', 'js', 'js']); 
    console.log('this should get printed when all the three files are loaded'); 


Но выход консольного:

this should get printed when all the three files are loaded 
scripts/module3.base.js:9 base is initialised 
scripts/module3.core.js:6 core is initialised 
scripts/module3.init.js:3 app is initialsed 

Похоже, первый вызов loadSync сам по себе является асинхронным вызовом

ответ

-1

вы можете загрузить их синхронно.

function get_contents(file){ 
    var xhr = new XMLHttpRequest(); 
    xhr.open('get', file, false); 
    xhr.send(); 
    return xhr.responseText; 
} 

function loadjscssfile(filename, filetype){ 
var content = get_contents(filename); 
if (filetype=="js"){ //if filename is a external JavaScript file 
    var fileref=document.createElement('script'); 
    fileref.setAttribute("type","text/javascript"); 
    fileref.innerHTML = content; 
} 
else if (filetype=="css"){ //if filename is an external CSS file 
    var fileref=document.createElement("link") 
    fileref.setAttribute("rel", "stylesheet") 
    fileref.setAttribute("type", "text/css") 
    fileref.innerHTML = content; 
} 
if (typeof fileref!="undefined") 
    document.getElementsByTagName("head")[0].appendChild(fileref) 
} 

Чтобы загрузить его наружно:

там уже 2 способами:

Обратный звонок как другой ответ.

Или вы можете сделать это:

function loadjscssfile(filename, filetype){ 
    if (filetype=="js"){ //if filename is a external JavaScript file 
     var fileref=document.createElement('script') 
     fileref.setAttribute("type","text/javascript") 
     fileref.setAttribute("src", filename) 
    } 
    else if (filetype=="css"){ //if filename is an external CSS file 
     var fileref=document.createElement("link") 
     fileref.setAttribute("rel", "stylesheet") 
     fileref.setAttribute("type", "text/css") 
     fileref.setAttribute("href", filename) 
    } 
    return fileref; 
} 

function loadSync(files,types){ 
    if(files[0] === 'undefined')return false; //if there's no files to load 
    var script = loadjscssfile(files[0],types[0]); //load first file 
    script.onload = function(){//after the script is loaded delete them and continue; 
     files.shift(); 
     types.shift(); 
     loadSync(files,types); 
    } 
    if (typeof script !="undefined") 
     document.getElementsByTagName("head")[0].appendChild(script) 
} 

loadSync(["myscript1.js","myscript2.js","myscript3.js"],['js','js','js']); 
+0

Я могу загрузить файлы, подобные этому, в правильной последовательности. Но теперь я не вижу их в разделе «Источники» инструментов для разработчиков Chrome (естественно, теперь мы добавляем разметку) – ankur

+0

, потому что теперь вы добавляете источник файла в встроенный тег скрипта, поэтому сценарий не является внешним, поскольку он имеет не 'src'. –

+0

Я не хочу этого. Я все еще хочу видеть их в разделе ресурсов. так что они остаются в отдельных файлах (как и должно быть) – ankur

0

для HTML5 просто использовать асинхронных атрибута (информацию на http://davidwalsh.name/html5-async)

Примера функции для загрузки сценария с опцией опционального обратного вызова

function loadScript(url, callback) { 
    if (!callback) callback = function() {}; 
    var script = document.createElement("script") 
    script.type = "text/javascript"; 
    script.setAttribute("async", "true"); 

    if (script.readyState){ //IE 
     script.onreadystatechange = function(){ 
      if (script.readyState == "loaded" || 
        script.readyState == "complete"){ 
       script.onreadystatechange = null; 
       callback(); 
      } 
     }; 
    } else { //Others 
     script.onload = function(){ 
      callback(); 
     }; 
    } 

    script.src = url; 
    document.getElementsByTagName("head")[0].appendChild(script); 
} 

Для получения смешанного раствора:

function loadjscssfile(url, type, callback) { 
    if (!type) { 
     type = "js"; 
    } 
    var node; 
    if (type === "js") { 
     var node = document.createElement("script") 
     node.setAttribute("async", "true"); 
     node.type = "text/javascript"; 

     if (node.readyState){ //IE 
      node.onreadystatechange = function(){ 
       if (node.readyState == "loaded" || 
         node.readyState == "complete"){ 
        node.onreadystatechange = null; 
        callback(); 
       } 
      }; 
     } else { //Others 
      node.onload = function(){ 
       callback(); 
      }; 
     } 

     node.src = url; 
    } else if (type === "css") { 
     var node = document.createElement("link") 
     node.type = "text/css"; 
     node.setAttribute("rel", "stylesheet"); 
     node.setAttribute("async", "true"); 

     if (node.readyState){ //IE 
      node.onreadystatechange = function(){ 
       if (node.readyState == "loaded" || 
         node.readyState == "complete"){ 
        node.onreadystatechange = null; 
        callback(); 
       } 
      }; 
     } else { //Others 
      node.onload = function(){ 
       callback(); 
      }; 
     } 
     node.href = url; 
    } 
    if (node) { 
     document.getElementsByTagName("head")[0].appendChild(node); 
    } else { 
     callback(new Error("File not found")); 
    } 
} 

Загрузка списка файлов

function loadjscssfileList(arr_original, callback) { 
    var arr = []; 
    arr_original.forEach(function (v) { 
     arr.push(v); 
    }); 
    var next = function() { 
     if (arr.length) { 
      var file = arr.shift(); 
      loadjscssfile(file[0], file[1], function() { 
       next(); 
      }); 
     } else { 
      callback(); 
     } 
    }; 
    next(); 
}; 


// use without callback 
loadjscssfileList([ 
    ["myscript.js","js"], 
    ["style.css","css"], 
    ["myscript2.js","js"] 
]); 

// use with callback 
loadjscssfileList([ 
    ["myscript.js","js"], 
    ["style.css","css"], 
    ["myscript2.js","js"] 
], function() { 
    alert("loaded") 
}); 
+0

Я не могу использовать модель обратного вызова, потому что это потребует от меня изменить существующую базу кода (виджеты javascript, модули и т. Д.), Чтобы вписаться в модель аддонов обратного вызова. – ankur

+0

callback не является обязательным –

+0

Я не собираюсь загружать их асинхронно. Идея заключается в том, чтобы загрузить их, как если бы они были написаны в нужной последовательности в ** ** раздела HTML страницы – ankur

1

Есть открытый источник JS, который облегчит вашу проблему. Вы можете использовать плагины LABJS или RequreJS.

Скейт-погрузчики, такие как LABJS, RequireJS, улучшат скорость и качество вашего кода.

Вы можете сохранить порядок загрузки своего скрипта в LABJS.

$LAB.setOptions({AlwaysPreserveOrder:true}) 
.script("script1.js") 
.script("script2.js") 

ИЛИ

$LAB 
.script("script1.js").wait() 
.script("script2.js") 

script2.js будет ждать до тех пор пока script1.js загружен.

Я думаю, это решит вашу проблему.

+0

Для LABjs важно отметить, что под «ожиданием» мы подразумеваем выполнение, а не загрузку.Все сценарии загружаются как можно лучше, для обеспечения максимальной производительности, но их выполнение упорядочивается в надлежащем порядке, если это необходимо. –