2010-06-13 4 views
14

Я пытаюсь написать ультра простое решение для загрузки кучи JS-файлов асинхронно. До сих пор у меня есть следующий сценарий. Однако обратный вызов иногда вызывается, когда сценарии фактически не загружаются, что вызывает ошибку, не найденную переменной. Если я обновляю страницу иногда, это просто работает, потому что я думаю, что файлы поступают прямо из кеша и, следовательно, быстрее, чем вызван обратный вызов, это очень странно?Async Загрузка файлов JavaScript с обратным вызовом

var Loader = function() { 

} 
Loader.prototype = { 
    require: function (scripts, callback) { 
     this.loadCount  = 0; 
     this.totalRequired = scripts.length; 
     this.callback  = callback; 

     for (var i = 0; i < scripts.length; i++) { 
      this.writeScript(scripts[i]); 
     } 
    }, 
    loaded: function (evt) { 
     this.loadCount++; 

     if (this.loadCount == this.totalRequired && typeof this.callback == 'function') this.callback.call(); 
    }, 
    writeScript: function (src) { 
     var self = this; 
     var s = document.createElement('script'); 
     s.type = "text/javascript"; 
     s.async = true; 
     s.src = src; 
     s.addEventListener('load', function (e) { self.loaded(e); }, false); 
     var head = document.getElementsByTagName('head')[0]; 
     head.appendChild(s); 
    } 
} 

Есть в любом случае, чтобы проверить, что файл JS полностью загружен, не ставя что-то в самом JS сам файл, потому что я хотел бы использовать ту же схему для загрузки библиотеки из моего контроля (GMaps и т.д.) ,

Вызов кода, непосредственно перед тегом.

var l = new Loader(); 
l.require([ 
    "ext2.js", 
    "ext1.js"], 
    function() { 
     var config = new MSW.Config(); 
     Refraction.Application().run(MSW.ViewMapper, config); 
     console.log('All Scripts Loaded'); 
    }); 

Спасибо за любую помощь.

+0

В каком браузере и версии вы тестируете? –

+0

В последнем WebKit он также входит в последнюю версию браузера Chrome :( – Gcoop

+0

Я не могу воспроизвести это с помощью Chromium 5.0.375.70, загрузив два сценария из CDN и один из localhost (содержащий функцию, необходимую для выполнения строка внутри функции обратного вызова). Но действительно ли существует флаг 'async'? Что произойдет, если вы прокомментируете' s.async = true; 'out? –

ответ

2

Там нет ничего плохого с кодом от того, что я могу сказать, что это просто ошибка в Chrome (он делает это с window.onload также.)

Я хотел бы добавить его в функцию, которая запускается в функции «load». Если переменная существует, выполните JS-код, но если это не так, используйте setTimeout для проверки снова через 500 мс или около того.

+0

Вы также можете проверить наличие функции: например, если вы хотите загрузить jQuery таким образом, вы можете проверить, что функция '' 'присутствует в глобальной области:' if ('$' in window)/* сделать что-то * /; ' –

+0

Спасибо также за эту проверку :) – Gcoop

2

Только в случае, если вы найдете это полезным, я создал утилиту библиотеки асинхронной, который позволит вам писать код выше как:

var Loader = function() {} 

Loader.prototype = { 
    require: function (scripts, callback) { 
     async.map(scripts, this.writeScript, callback); 
    }, 
    writeScript: function(src, callback) { 
     var s = document.createElement('script'); 
     s.type = "text/javascript"; 
     s.src = src; 
     s.addEventListener('load', function (e) { callback(null, e); }, false); 
     var head = document.getElementsByTagName('head')[0]; 
     head.appendChild(s); 
    } 
} 

Если вы делаете много асинхронных вызовов это некоторые весьма мощные функции :)

http://caolanmcmahon.com/async.html

4

насчет JQuery ....

$.getScript('abc.js'); 

Выше код загрузит файл сценария «abc.js» асинхронно ....

+2

Я использую xui уже и не хочу включать в себя среду jQuery, она просто добавит лишний вес :) Хотя я не знал, что jQuery может это сделать, спасибо! – Gcoop

+0

'getScript' не имеет обратного вызова, который вызывается после выполнения скрипта. – Flimm

0

Как и Аарон, в Chrome есть ошибка, но есть проблемы и с IE, и с другими браузерами.

I судимого различные способы создания моего ленивый загрузчика и я имел много проблем:

  • добавив < скрипт > тега: проблемы с скриптовыми событиями (. OnLoad, OnError и т.д.) в Проводнике и другом браузеры
  • чтение скрипта с ajax и разбор текста (с eval, это javascript, поэтому не беспокойтесь, это не evIl): ОЧЕНЬ сложно отлаживать (он анализируется как одна строка без комментариев, поэтому вы не можете знать, какую строку дает вам ошибку)
  • чтение сценария с помощью ajax и добавление < скрипт > тег с текстом скрипта: очень хорошо работает во всех браузерах; вы можете создавать асинхронную и синхронизацию с той же функцией, а также можете очень хорошо управлять ошибками, загрузкой и т. Д. (Если вы знаете основы ajax, вы должны знать, как обращаться с переменным состоянием http), и это то, что я рекомендую.
3

Я рекомендую вам использовать крошечный загрузчик Javascript, как JcorsLoader (только 647B с Gzip)

JcorsLoader.load(
       "http://xxxx/jquery.min.js", 
       function() { 
        $("#demo").html("jQuery Loaded"); 
       }, 
       "http://xxxx/jquery.cookie.js", 
       function() { 
        $.cookie('not_existing'); 
       } 
      ); 

нагрузки кратные JS параллельно и выполнять в порядке, не блокируя DOMReady или OnLoad.

https://github.com/pablomoretti/jcors-loader

0

jcors-loader.js не работает в Internet Explorer ...

index.html

<html> 
    <head> 
    <script type="text/javascript" src="/js/jcors-loader.js"></script> 
    <script> 
     JcorsLoader.load(
       "js/jquery-1.8.0.js", 
       "/js/alertme.js", 
       function() { 
        $("#result").text("TEST OK"); 
       } 
     ); 

    </script> 
    </head> 
    <body> 
    <h1 id="result"></h1> 
    </body> 
    </html> 

alertme.js

предупреждение (» Loaded ");

Это прекрасно работает в режиме chrome и firefox, на экране отображается «TEST OK» и всплывающее окно ... Но в IE нет сообщений или оповещений (7,8,9) ... Любая помощь будет оценена.

-1

Aku menggabungkan scrpit callback dengan всплывающая подсказка, didalam template blogger. kemudian didalamnya ditambahkan сценарий callbak menggunakan Javascipt

Script callback with tooltip

<style> 
 
/* Tooltip container */ 
 
.tooltip { 
 
    position: relative; 
 
    display: inline-block; 
 
    text-transform: italic; 
 
    color: blue; 
 
    border-bottom: 1px dotted black; 
 
} 
 

 

 
.tooltip .tooltiptext { 
 
    visibility: hidden; 
 
    width: 400px; 
 
    background-color: #fff; 
 
    border: 2px solid #cc6611; 
 
    color: black; 
 
    text-align: left; 
 
\t top: 0; left: 6px; 
 
    border-radius: 6px; 
 
\t box-shadow: 0 2px 4px -2px #716e6c; 
 
    padding: 15px; 
 
    position: absolute; 
 
    z-index: 999; 
 
    top: 90%; 
 
    left: 10%; 
 
    margin-left: -10px; 
 
} 
 

 
.tooltip .tooltiptext::after { 
 
    content: ""; 
 
    position: absolute; 
 
    bottom: 100%; 
 
    left: 10%; 
 
    margin-left: -10px; 
 
    border-width: 10px; 
 
    border-style: solid; 
 
    border-color: transparent transparent #cc6611 transparent; 
 
} 
 

 
.tooltip:hover .tooltiptext { 
 
    visibility: visible; 
 
} 
 
</style> 
 

 
<span class='tooltip'><span class='tooltiptext'><script> 
 
document.write("<script src=\"/feeds/posts/default/-/Your Label Post?max-results="+numposts4+"&orderby=published&alt=json-in-script&callback=showrecentposts4\"><\/script>"); 
 
</script> 
 
</span></span>
<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
<script type='text/javascript'> 
 
//<![CDATA[ 
 

 
imgr = new Array(); 
 
imgr[0] = "http://2.bp.blogspot.com/-uitX7ROPtTU/Tyv-G4NA_uI/AAAAAAAAFBY/NcWLPVnYEnU/s1600/no+image.jpg"; 
 
showRandomImg = true; 
 
aBold = true; 
 
summaryPost = 170; 
 
summaryPost4 = 160; 
 
summaryTitle = 100; 
 
numposts = 10; 
 
numposts4 = 5; 
 

 
function removeHtmlTag(strx,chop){ 
 
    var s = strx.split("<"); 
 
    for(var i=0;i<s.length;i++){ 
 
     if(s[i].indexOf(">")!=-1){ 
 
      s[i] = s[i].substring(s[i].indexOf(">")+1,s[i].length); 
 
     } 
 
    } 
 
    s = s.join(""); 
 
    s = s.substring(0,chop-1); 
 
    return s; 
 
} 
 

 
function showrecentposts(json) { 
 
    j = (showRandomImg) ? Math.floor((imgr.length+1)*Math.random()) : 0; 
 
    img = new Array(); 
 

 
     for (var i = 0; i < numposts; i++) { 
 
     var entry = json.feed.entry[i]; 
 
     var posttitle = entry.title.$t; 
 
     var pcm; 
 
     var posturl; 
 
     if (i == json.feed.entry.length) break; 
 
     for (var k = 0; k < entry.link.length; k++) { 
 
       if (entry.link[k].rel == 'alternate') { 
 
       posturl = entry.link[k].href; 
 
       break; 
 
       } 
 
     } 
 
     
 
     for (var k = 0; k < entry.link.length; k++) { 
 
       if (entry.link[k].rel == 'replies' && entry.link[k].type == 'text/html') { 
 
       pcm = entry.link[k].title.split(" ")[0]; 
 
       break; 
 
       } 
 
     } 
 
     
 
     if ("content" in entry) { 
 
       var postcontent = entry.content.$t;} 
 
     else 
 
     if ("summary" in entry) { 
 
       var postcontent = entry.summary.$t;} 
 
     else var postcontent = ""; 
 
     
 
     postdate = entry.published.$t; 
 
    
 
    if(j>imgr.length-1) j=0; 
 
    img[i] = imgr[j]; 
 
    
 
    s = postcontent ; a = s.indexOf("<img"); b = s.indexOf("src=\"",a); c = s.indexOf("\"",b+5); d = s.substr(b+5,c-b-5); 
 

 
    if((a!=-1)&&(b!=-1)&&(c!=-1)&&(d!="")) img[i] = d; 
 

 
    //cmtext = (text != 'no') ? '<i><font color="'+acolor+'">('+pcm+' '+text+')</font></i>' : ''; 
 

 

 
    var month = [1,2,3,4,5,6,7,8,9,10,11,12]; 
 
    var month2 = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]; 
 

 
    var day = postdate.split("-")[2].substring(0,2); 
 
    var m = postdate.split("-")[1]; 
 
    var y = postdate.split("-")[0]; 
 

 
    for(var u2=0;u2<month.length;u2++){ 
 
     if(parseInt(m)==month[u2]) { 
 
      m = month2[u2] ; break; 
 
     } 
 
    } 
 

 
    var daystr = day+ ' ' + m + ' ' + y ; 
 
    
 
    var trtd = '<li style="position:relative;"><div class="imgauto"><a href="'+posturl+'"><img width="200" height="150" class=" " src="'+img[i]+'"/></a></div><h3><a href="'+posturl+'">'+posttitle+'</a><p>'+daystr+'/'+pcm+' comments</p></h3></li>';      
 
     document.write(trtd); 
 
       
 
       j++; 
 
    } 
 
    
 
} 
 

 
function showrecentposts4(json) { 
 
\t j = (showRandomImg) ? Math.floor((imgr.length+1)*Math.random()) : 0; 
 
\t img = new Array(); 
 
    if (numposts4 <= json.feed.entry.length) { 
 
\t \t maxpost = numposts4; 
 
\t \t } 
 
\t else 
 
     { 
 
\t maxpost=json.feed.entry.length; 
 
\t } \t 
 
    \t for (var i = 0; i < maxpost; i++) { 
 
    \t var entry = json.feed.entry[i]; 
 
    \t var posttitle = entry.title.$t; 
 
\t \t var pcm; 
 
    \t var posturl; 
 
    \t if (i == json.feed.entry.length) break; 
 
    \t for (var k = 0; k < entry.link.length; k++) { 
 
     \t \t if (entry.link[k].rel == 'alternate') { 
 
     \t \t posturl = entry.link[k].href; 
 
     \t \t break; 
 
     \t \t } 
 
    \t } 
 
\t \t 
 
\t \t for (var k = 0; k < entry.link.length; k++) { 
 
     \t \t if (entry.link[k].rel == 'replies' && entry.link[k].type == 'text/html') { 
 
     \t \t pcm = entry.link[k].title.split(" ")[0]; 
 
     \t \t break; 
 
     \t \t } 
 
    \t } 
 
\t \t 
 
    \t if ("content" in entry) { 
 
     \t \t var postcontent = entry.content.$t;} 
 
    \t else 
 
    \t if ("summary" in entry) { 
 
     \t \t var postcontent = entry.summary.$t;} 
 
    \t else var postcontent = ""; 
 
    \t 
 
    \t postdate = entry.published.$t; 
 
\t 
 
\t if(j>imgr.length-1) j=0; 
 
\t img[i] = imgr[j]; 
 
\t 
 
\t s = postcontent \t ; a = s.indexOf("<img"); b = s.indexOf("src=\"",a); c = s.indexOf("\"",b+5); d = s.substr(b+5,c-b-5); 
 

 
\t if((a!=-1)&&(b!=-1)&&(c!=-1)&&(d!="")) img[i] = d; 
 

 
\t //cmtext = (text != 'no') ? '<i><font color="'+acolor+'">('+pcm+' '+text+')</font></i>' : ''; 
 

 

 
\t var month = [1,2,3,4,5,6,7,8,9,10,11,12]; 
 
\t var month2 = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]; 
 

 
\t var day = postdate.split("-")[2].substring(0,2); 
 
\t var m = postdate.split("-")[1]; 
 
\t var y = postdate.split("-")[0]; 
 

 
\t for(var u2=0;u2<month.length;u2++){ 
 
\t \t if(parseInt(m)==month[u2]) { 
 
\t \t \t m = month2[u2] ; break; 
 
\t \t } 
 
\t } 
 

 
\t var daystr = day+ ' ' + m + ' ' + y ; 
 
    pcm='<a href="'+posturl+'">'+pcm+' comments</a>'; 
 
\t 
 
if (i==0) { 
 
\t var trtd = '<div class="entry-thumb"><a href="'+posturl+'"><img width="70" height="70" src="'+img[i]+'"/></a></div><h3 class="entry-title"><a href="'+posturl+'">'+posttitle+'</a></h3><div class="entry-meta"></div><div class="entry-excerpt"><p>'+removeHtmlTag(postcontent,summaryPost4)+'...</p></div>'; 
 
\t document.write(trtd); 
 
} 
 
if ((i>0)&&(i<maxpost)) 
 
    { 
 
\t var trtd = '<li class="catlist"><a href="'+posturl+'">'+posttitle+'</a></li>'; 
 
\t document.write(trtd); 
 
} 
 
\t j++; 
 
} 
 

 
} 
 

 
//]]> 
 
</script> 
 
</head> 
 

 
<body>

И вы можете увидеть демо на harga lantai kayu

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