Javascript insertion on page from Chrome extension: concurrency problem?

I am involved in the development of the Chrome extension.

At some point, we need to run some static, non-generated code that should run in the context of the page, not the extension.

For simple scripts, there is no problem using $.getScript(chrome.extension.getURL(....)) or script = document.createElement('script'); ... document.body.appendChild(script); script = document.createElement('script'); ... document.body.appendChild(script);

For more complex scripts, we sometimes need to include jquery or another script definition (due to dependencies).

In this latter case, while Javascript is supposedly single-threaded, it seems that jQuery is not parsed completely when the script dependency is executed, resulting in the following

 Uncaught ReferenceError: $ is not defined 

Am I mistaken in assuming JScript is single-threaded? What is the correct way to enter scripts on a page if there are dependencies between these scripts? (e.g. script X uses the function defined in script Y)

+6
source share
2 answers

You can use the onload event for the script ....

 function addScript(scriptURL, onload) { var script = document.createElement('script'); script.setAttribute("type", "application/javascript"); script.setAttribute("src", scriptURL); if (onload) script.onload = onload; document.documentElement.appendChild(script); } function addSecondScript(){ addScript(chrome.extension.getURL("second.js")); } addScript(chrome.extension.getURL("jquery-1.7.1.min.js"), addSecondScript); 
+9
source

Adding a script element with the src attribute to the DOM does not mean that the script is actually loaded and ready to use. You will need to keep track of when the script is really loaded, after which you can start using jQuery as usual.

You can do something like this:

  var script = doc.createElement("script"); script.src = url; /* if you are just targeting Chrome, the below isn't necessary script.onload = (function(script, func){ var intervalFunc; if (script.onload === undefined) { // IE lack of support for script onload if( script.onreadystatechange !== undefined ) { intervalFunc = function() { if (script.readyState !== "loaded" && script.readyState !== "complete") { window.setTimeout( intervalFunc, 250 ); } else { // it is loaded func(); } }; window.setTimeout( intervalFunc, 250 ); } } else { return func; } })(script, function(){ // your onload event, whatever jQuery etc. }); */ script.onload = onreadyFunction; // your onload event, whatever jQuery etc. document.body.appendChild( script ); 
+4
source

Source: https://habr.com/ru/post/911566/


All Articles