2012-03-24 19 views
6

我正在参与开发Chrome扩展。从Chrome扩展程序的页面中注入Javascript:并发问题?

在某些时候,我们需要运行一些静态的非生成代码,它必须在页面的上下文中运行,而不是扩展名。

对于简单的脚本,是没有问题的,即使用$.getScript(chrome.extension.getURL(....))要么script = document.createElement('script'); ... document.body.appendChild(script);

对于更复杂的脚本,我们需要有时incluque jQuery的本身,或其他一些脚本定义(由于依存关系)。

在后一种情况下,虽然,尽管事实上,JavaScript是所谓单线程的,似乎jQuery是不会被解析完全当dependend脚本的运行,从而导致以下

Uncaught ReferenceError: $ is not defined 

我错了当假设JScript是单线程? 当这些脚本之间存在依赖关系时,在页面中注入脚本的正确方法是什么? (例如,脚本X使用在脚本Y中定义的功能)

回答

9

您可以使用onload事件的脚本....

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); 
+0

这工作。我写了一个链接机制,但是使用onload属性确实是需要的。谢谢! – 2012-03-24 16:24:03

4

在DOM中附加script元素与src属性并不意味着脚本实际上已加载并且可以使用。您需要监视脚本实际加载的时间,之后您可以像平常一样开始使用jQuery。

你可以做这样的事情:

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