How to make a function wait for jQuery loaded with the async tag

7

I have a problem to make a function wait for loading the package.js with the async tag

<script id="packjs" async type="text/javascript" src="pacote.js"></script>

This file contains jQuery and some plugins. The problem is that when I load with async I have to sort out a way to do the functions on the page and wait for loading the package.js, I found some solutions that worked in < strong FF and IE , but Chrome sometimes does not work depending on the loading order.

What I've already tried:

document.getElementById('packjs').addEventListener("load", chamoUmaFuncaoAqui,false);

It would be the perfect solution, and it works on FF and IE , but on Chrome , I do not know why. Sometimes this event does not work and activates the function at the beginning, so before the package.js. I tried combining with a var statement at the end of the .js package and then check if it exists,

if (typeof pronto !== 'undefined') {
    chamoUmaFuncaoAqui();
}

But it also did not work.

function init() {
    if (window.jQuery) {
        // Código dependente do jQuery fica aqui
        tempo=Date.now()-timestamp;
        console.log('Alternativa Função init com setTimeout (se ocorrer depois de window.addEventListener load não funcionará):  '+tempo);
        //car_news();
        //Car_Com();
    } else {
        window.setTimeout(init, 100);
    }
}
init();

The problem is that when loading is very fast, the time difference between the function and the window.addEventListener load event is one thousandths of a second, and if it runs later, it does not work.

my page with this test and some of the options I've tested. I left everything with console.log to follow the problem. I do not have such a great knowledge in javascript, but I believe the problem has only occurred in Chrome when it for some reason (I believe wrongly) gives window.addEventListener DOMContentLoaded before loading the .js file (this does not occur in other browsers)

Does anyone know how to get around this? If you can be as an example, thank you.

Resolved, (I think, rs). before calling the .js file I added:

var pronto = false; var feito=false;

from within the .js file I added: ronto = true;

if (feito==false && typeof executa !== 'undefined')
 {feito=true;executa('Chamado de dentro do Arquivo PACK.JS ');};

On the page I created a second call if it has not been called from within the .js file yet

if (pronto==true && feito==false) 
{feito=true;executa('Chamado pela PAGINA ');}

But what solved it was to create a condition within the function executes to check whether the document.addEventListener "DOMContentLoaded" was already happening or not. That's because in Chrome with async the file might happen to be loaded before this event, it did not seem to occur to me in FF and IE. So, the page looks like this:

function executa(a){
   if (DOMpronto==true) {
   /*o que precisar ANTES do DOM ter sido carregado*/
 }else{
   /*o que precisar DEPOIS do DOM ter sido carregado*/
 }
}

function evento(f) {
        if (window.addEventListener)
            {window.addEventListener("load", f,false);}
        else if (window.attachEvent)
            {window.attachEvent("onload", f,false);}
        else
            {window.onload = f;}    
}
var DOMpronto=false
evento(function(){console.log('carregoru DOM ');DOMpronto=true})    
if (pronto==true && feito==false) {feito=true;executa('pela PAGINA ');}

I gave a pro's summary which is pertinent, but that's basically it and it worked. Thank you for your attention.

    
asked by anonymous 27.11.2015 / 12:36

2 answers

1
  • Create a callback
  • Seven in your variable file as true
  • Use setInterval to create a scan continue through the variable

File1.js

var pronto = false;

function callback(){
    if(pronto == true){
        // ... codigo ...

        clearInterval(call);
    }
}

var call = setInterval(callback, 10);

File2.js

pronto = true;

Explanation

In File1 you are creating a loop that only ends when pronto == true , because at the end we have clearInterval(call); .

    
27.11.2015 / 12:47
1

You can use the gowiththeflow library to help you with this.

To create a run stream, instantiate an object of type Flow , then call the par method to execute something in parallel or seq for sequenced actions.

For event tag script , use load and readystatechange for compatibility purposes.

var scripts = [
  { id: 'script1', flow: 'par', src: 'https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js' },
  { id: 'script2', flow: 'par', src: 'https://code.jquery.com/jquery-2.1.4.js' },
  { id: 'script3', flow: 'seq', src: 'https://cdnjs.cloudflare.com/ajax/libs/globalize/1.0.0/globalize.js' },
  { id: 'script4', flow: 'par', src: 'https://cdnjs.cloudflare.com/ajax/libs/foundation/6.0.1/js/foundation.js' },
  { id: 'script5', flow: 'par', src: 'https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.10/js/jquery.dataTables.js' },
  { id: 'script6', flow: 'seq', src: 'https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.10/js/dataTables.foundation.js' }
]

var loadScript = function (id, url, callback)
{
  var request = new XMLHttpRequest();
  var script = document.createElement("script");
  
  //compatibilidade entre Browsers;
  script.onreadystatechange = callback;
  script.onload = callback;
  
  script.id = id;
  script.async = true;
  script.type = 'text/javascript';
  script.src = url;  
  
  document.head.appendChild(script);
}

var flow = new Flow();
[].forEach.call(scripts, function (script, indice) {
 
  flow[script.flow](function (next) {
    loadScript(script.id, script.src, function () {
      var date = new Date();
      console.log(script.id + " carregado às: " + date.toLocaleTimeString() + '.' + date.getMilliseconds());
      next();
    })
  });
});

flow.seq(function (next) {
  console.log('olha o jquery: ' + $)
});
<script src="https://rawgit.com/jeromeetienne/gowiththeflow.js/master/gowiththeflow.js"></script>

Theabovescriptwillcallthescript1andscript2scriptsinparallel...attheendoftheirexecution,itcallsthescript3,script4andscript5inparallel,attheendofthesecalls.script6.

Hereisthemincedscriptofgowiththeflow(606Bytes)(youcanevenplaceitnexttothescriptthatloadstheotherscripts):

varFlow=function(){vard,a=[],b=setTimeout(function(){b=null;d._next()},0);returnd={destroy:function(){b&&clearTimeout(b)},par:function(j,b){(b||!(a[a.length-1]instanceofArray))&&a.push([]);a[a.length-1].push(j);returnd},seq:function(a){returnd.par(a,!0)},_next:function(b,k){for(vare=[],f=[],g=a.shift()||[],h=g.length,i=1==h,c=0;c<g.length;c++)(function(a,c){a(function(a,b){e[c]=a;f[c]=b;0==--h&&d._next(i?e[0]:e,i?f[0]:f)},b,k)})(g[c],c)}}};"undefined"!==typeof module&&"exports"in module&&(module.exports=Flow);"function"===typeof define&&define.amd&&define("Flow",[],function(){return Flow});
    
27.11.2015 / 13:55