Search code examples
jquerygoogle-chromeuserscripts

How to get two chrome userscripts to use just one jQuery instance?


In my userscripts, I use this code to get jQuery and rest of my code injected and executed:

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)


This works perfectly. But when I have two scripts they both inject the jQuery part. The scripts need to be separate, because I don't know who wants to use which script or both scripts.

Can I prevent the second script from injecting jQuery and use the one from the first script?

When the second script directly starts with:

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)

I get the error Message in the console: jQuery is undefined. How can I test if a different script already injected jQuery and then wait until it's ready?


Solution

  • Give your jQuery a unique identifier, check for that identifier, and only add jQuery if it is not found. You'll also need to allow enough to time for the first jQuery to initialize.

    Changing addJQuery() to the following, in both scripts, works in my tests:

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