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

Asked

Viewed 1,691 times

7

I’m having a problem making a Function wait the loading of 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 find a way to do the functions on the page and wait for the loading of the package.js, I found some solutions that worked on FF and IE, most in the Chrome sometimes doesn’t work depending on the loading order.

what I have tried:

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

It would be the perfect solution, and it works on FF and IE, but in the Chrome, I don’t know why. Sometimes this event doesn’t work and activates the function right at the beginning, so before the.js package. I tried to combine it with a var statement at the end of the.js package and then check if it exists,

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

but it didn’t work either.

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 charging is too fast, the time difference between the function and the event window.addEventListener load is thousandths of seconds, and if it runs later, it doesn’t work.

my page with that test and some of the options I’ve tried. I left everything with console.log to keep up with the problem. I do not have such a great knowledge en javascript, but I believe that the problem has occurred only in Chrome when he for some reason (I think wrongly) gives the window.addEventListener Domcontentloaded before loading the.js file (this does not occur in other browsers)

Any know how to get around this? If it can be with example thank you.

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

var pronto = false; var feito=false;

from within the.js file added: Roint=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 yet been called from within the.js file

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

But what he decided to do was create a condition inside the Function executes to check if the Document.addeventlistener "Domcontentloaded" already happened or not. That’s because in async Chrome the file might happen to be uploaded before that event, it didn’t seem to occur in FF and IE. So on the page it was 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 summary for what is pertinent, but basically that’s it and it worked. Thank you for your attention

  • Behold setTimeout/setInterval, setTimeout only runs once, it would not be necessary to create a loop?

  • 1

    In my Chrome seemed to work normally your callback. But try this: document.getElementById('packjs').onreadystatechange = function() { if (script.readyState == 'loaded') { console.log("CARREGOU") } };. I wouldn’t be monitoring with timers.

2 answers

1

  • Create a callback
  • Seven in your file to variable as true
  • Use setInterval to create a check continue by 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 in the end we have clearInterval(call);.

  • Thank you for your attention, gave a problem similar to the example 2 q cited. , and sometimes it occurs after the window.addeventlistener load and it doesn’t work ================= File js loaded 73; window.addeventlistener Domcontentloaded 82; window.addeventlistener load 154; callback test): 155;

1

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

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

regarding the tag event script, use the load and the 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>

The above script will call the scripts script1 and script2 in parallel... to the end of the execution of the same, calls the script3, script4 and script5 in parallel, at the end of these calls the script6.

Follow the minified script of gowiththeflow (606 Bytes) (you can even put it next to the script that loads the other scripts):

var Flow=function(){var d,a=[],b=setTimeout(function(){b=null;d._next()},0);return d={destroy:function(){b&&clearTimeout(b)},par:function(j,b){(b||!(a[a.length-1]instanceof Array))&&a.push([]);a[a.length-1].push(j);return d},seq:function(a){return d.par(a,!0)},_next:function(b,k){for(var e=[],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});
  • thanks for your attention, , in case I only have one.js file, and what I need to do is to call the html page only after the function is available, in case the only.js file is available.

  • Another point in this case is that besides using async to make the load faster, not have . js loaded synchronously (without async), earn points on google pagespeed, q influences tb in ranking in google search. Soon load another auxiliary file like jhead, or Labs, or other, can resolve a part of the sync, but not at least one file will end up having q call without async

  • the minified script of this library has only 606 bytes, even if you add it at the top of your script, it should not increase the size of your application significantly, at the end you may only have a small script being loaded initially, the other scripts and styles will be loaded dynamically by this first.

  • in case you could give me an example of how to call only a single.js file and call a Function on the same page q is loading that library? , i.e., how do I call Function depending on that file loaded with gowiththeflow? thanks again for the return

  • I do not advise you to execute scripts inside the HTML page, give preference to external files, but in any case, you can do flow.seq(function (next) { /*Seu script aqui*/; next() });

Browser other questions tagged

You are not signed in. Login or sign up in order to post.