从Chrome扩展程序在页面中注入Javascript:并发问题?

时间:2012-03-24 12:01:24

标签: javascript jquery google-chrome google-chrome-extension

我正在参与Chrome扩展程序的开发。

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

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

对于更复杂的脚本,我们有时需要包含jquery本身或其他一些脚本定义(因为依赖)。

在后一种情况下,尽管Javascript应该是单线程的,但是当运行dependend脚本时,似乎没有完全解析JQuery,导致以下内容

Uncaught ReferenceError: $ is not defined

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

2 个答案:

答案 0 :(得分: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);

答案 1 :(得分: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 );