如何让两个chrome用户脚本只使用一个jQuery实例?

时间:2012-04-21 04:05:38

标签: jquery google-chrome userscripts

在我的用户脚本中,我使用此代码来获取jQuery并注入和执行其余代码:

function addJQuery(callback) {
  var script = document.createElement("script");
  script.setAttribute("src", "http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js");
  script.addEventListener('load', function() {
    var script = document.createElement("script");
    script.textContent = "(" + callback.toString() + ")();";
    document.body.appendChild(script);
  }, false);
  document.body.appendChild(script);
}
function readyJQuery() {
  jQuery.noConflict();
  jQuery(document).ready(function() {
    //my rest code goes here
  })
}
addJQuery(readyJQuery)


这非常有效。但是当我有两个脚本时,它们都会注入jQuery部分。脚本需要分开,因为我不知道谁想要使用哪个脚本或两个脚本。

我可以阻止第二个脚本注入jQuery并使用第一个脚本中的那个吗?

当第二个脚本直接以:

开头时
function addJQuery(callback) {
  var script = document.createElement("script");
  script.textContent = "(" + callback.toString() + ")();";
  document.body.appendChild(script);
}
function readyJQuery() {
  jQuery.noConflict();
  jQuery(document).ready(function() {
    //my rest code goes here
  })
}
addJQuery(readyJQuery)

我在控制台中收到错误消息:jQuery is undefined。 我怎样才能测试一个不同的脚本是否已经注入了jQuery,然后等到它准备好了?

2 个答案:

答案 0 :(得分:1)

为jQuery提供唯一标识符,检查该标识符,如果找不到jQuery,则只添加jQuery。您还需要足够的时间来初始化第一个jQuery。

在两个脚本中将addJQuery()更改为以下内容,可以在我的测试中使用:

function addJQuery (callback) {
    //--- Has jQuery already been added?
    var jqNode  = document.querySelector ("#myAddedJQ");
    if (jqNode) {
        FireCallback (callback);
    }
    else {
        //--- Wait a bit to be sure.
        setTimeout ( function() {
                var jqNode  = document.querySelector ("#myAddedJQ");
                if (jqNode) {
                    FireCallback (callback);
                }
                else {
                    var script  = document.createElement ("script");
                    script.id   = "myAddedJQ";
                    script.setAttribute (
                        "src",
                        "http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"
                    );
                    script.addEventListener ('load', function () {
                        FireCallback (callback);
                    }, false);
                    document.body.appendChild (script);
                }
            }
            , 444
        );
    }

    function FireCallback (callback) {
        var script          = document.createElement ("script");
        script.textContent  = "                                         \
            if (typeof waitForJqDefined == 'undefined') {               \
                var waitForJqDefined    = setInterval ( function () {   \
                        if (typeof jQuery != 'undefined') {             \
                            clearInterval (waitForJqDefined);           \
        ";
        script.textContent += "\n(" + callback.toString() + ")();\n";
        script.textContent += "                                         \
                        }                                               \
                    },                                                  \
                    50                                                  \
                );                                                      \
            }                                                           \
            else {                                                      \
        ";
        script.textContent += "\n(" + callback.toString() + ")();\n";
        script.textContent += "                                         \
            }                                                           \
        ";
        document.body.appendChild (script);
    }
}

答案 1 :(得分:0)

在注入脚本以加载jQuery之前 - 为什么不检查它是否已经存在?

如果您担心竞争条件:两个脚本都试图同时加载它 - 您可以通过在全局范围内设置一个标志来缩小该竞争条件并检查它。不会消除竞争条件,但可能有所帮助。

if ( typeof jQueryLoading == 'undefined')
   var jQueryLoading = false;
if ( typeof jQuery == 'undefined' && jQueryLoading == false )
{
  jQueryLoading = true;
  //Load it yourself, then add scripts
}
else
{
  //No problems. Add your scripts
}