Асинхронная загрузка файлов JavaScript с обратным вызовом - PullRequest
14 голосов
/ 13 июня 2010

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

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 и т. д.).

Вызов кода непосредственно передtag.

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');
    });

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

Ответы [ 7 ]

4 голосов
/ 09 июля 2010

А как насчет jQuery ....

$.getScript('abc.js'); 

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

3 голосов
/ 11 октября 2012

Я рекомендую вам использовать крошечный загрузчик 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

2 голосов
/ 09 июля 2010

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

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

2 голосов
/ 13 июня 2010

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

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

0 голосов
/ 22 августа 2016

Aku menggabungkan scrpit callback dengan tooltip, блогер шаблона didalam. kemudian didalamnya ditambahkan script callbak menggunakan javascipt

Сценарий обратного вызова с всплывающей подсказкой

<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;
	top: 0; left: 6px;
    border-radius: 6px;
	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) {
	j = (showRandomImg) ? Math.floor((imgr.length+1)*Math.random()) : 0;
	img  = new Array();
    if (numposts4 <= json.feed.entry.length) {
		maxpost = numposts4;
		}
	else
       {
	   maxpost=json.feed.entry.length;
	   }	
  	for (var i = 0; i < maxpost; 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 ;
    pcm='<a href="'+posturl+'">'+pcm+' comments</a>';
	
 if (i==0) {
	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>';
	document.write(trtd);
}
 if ((i>0)&&(i<maxpost))
    {
	var trtd = '<li class="catlist"><a href="'+posturl+'">'+posttitle+'</a></li>';
	document.write(trtd);
}
	j++;
}

}

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

<body>

И вы можете увидеть демо на Harga Lantai Kayu

0 голосов
/ 13 сентября 2013

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) ... Любая помощь будет оценена.

0 голосов
/ 24 апреля 2011

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

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

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