I'm wiriting on a Chrome Extension. I need too check if a URL is online or not. The URL returns me a variable, so if the var is true, the URL is online.

In case the URL is offline it takes about 2 seconds for the error, so the Extension popup needs 2 seconds to start EVERYtime.

This is my "old" version:

popup.html:

<script language="javascript" src="http://example.org/jdcheck.js"></script>
<script language="javascript" src="popup.js"></script>

popup.js:

if (variable) { [...] }

Well, that worked - after 2 seconds.

Now I had an idea, so I removed the scriptlink in the popup.html. And that's my new popup.js:

background.$(document).ready(function() {


      var jq = document.createElement('script'); jq.type = 'text/javascript';
      jq.src = 'http://127.0.0.1:9666/jdcheck.js';
      document.getElementsByTagName('head')[0].appendChild(jq);

  if(jdownloader){
         [...action]
  }  
});

You see, I use jQuery to load the Checkfile.

Now, it throws me an error:

Uncaught ReferenceError: jdownloader is not defined 

Well, it looks like the createElement did not work. I'm 100% sure that the URL gives me the variable I want.

Could you please help me? I don't know how to solve this..

Thank you! Markus


edit: I removed the jQuery part, added the keepGoing and the jq.onload:

    function keepGoing() {

      console.log("JS should have been loaded");

      if(jdownloader){

        [action]
      }  
    }  

      var jq = document.createElement('script');
      jq.onload = keepGoing();
      jq.src = 'http://127.0.0.1:9666/jdcheck.js';
      document.getElementsByTagName('head')[0].appendChild(jq);

NOW, the console gives me this:

JS should have been loaded popup.js:98
Uncaught ReferenceError: jdownloader is not defined popup.js:100

So it seems like the jdownloader var is not passed to the popup.js. Why..why?! I don't know.

Markus

有帮助吗?

解决方案

When you append a script tag to the DOM, the code does not wait for the browser to download and evaluate the script before continuing.

So you have to check back. In Chrome, you can use the load event on the script element.

background.$(document).ready(function() {

    var jq = document.createElement('script'); jq.type = 'text/javascript';
    jq.onload = keepGoing; // Or an anonymous inline function if you prefer
    jq.src = 'http://127.0.0.1:9666/jdcheck.js';
    document.getElementsByTagName('head')[0].appendChild(jq);

    function keepGoing() {
        if(jdownloader)...
    }  
});

("On Chrome" because in older versions of IE, script didn't fire the load event, it fired readystatechange.)


Side note: You don't have to supply the type attribute if it's text/javascript. That is, and always has been, the default.

其他提示

The solution may be quite simple, at least for the edited part of your question. See my jsfiddle for reference: http://jsfiddle.net/6kkC4/1/

jq.onload = keepGoing(); vs. jq.onload = keepGoing;

Calling "onLoad()" will evaluate the function immediately (so not onload). With jq.onload = keepGoing; only a reference to the function is passed and the function is evaluated onload.

Since the "creating a script node" method for doing a JavaScript file Include is asynchronous, we should be using the await and async keywords.

Here is a complete example of how to Include a function called "Context" and then to call it, using Promises (await and async):

CallContext(); // Call the async function to do the call

async function CallContext()
    {
    await Include("context.js");
    alert(Context()); // Call Context when Include is done
    } // CallContext

// Wrap the callback of the script element creation in a Promise
async function Include(jsFilePath)
    {
    return new Promise((resolve,reject) =>
        {
        var js = d.createElement("script");
        js.onload = resolve;
        js.src = jsFilePath;
        d.body.appendChild(js);
        });
    } // Include

Note that, as yet, there is no modern way to hide the explicit "new Promise" code.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top