Question

I'm making a bookmarklet which will load jQuery if the object is not found. The loading will check on the version of jQuery. The code is like:

(function(){

    var myBkl = {
         loadScript: function(src) {
            if(window.jQuery && window.jQuery.fn.jquery == '1.3.2'){
                return;
            }
            var s = document.createElement('script');
            s.setAttribute('src', src);
            s.setAttribute('type', 'text/javascript');
            document.getElementsByTagName('head')[0].appendChild(s); 
        },
        whenLoaded: function(callback){
            if (typeof(window.jQuery) !== 'undefined' && window.jQuery.fn.jquery == '1.3.2') { 
                callback(window.jQuery); 
            } 
            else {
                setTimeout((function() {myBkl.whenLoaded(callback); }), 100);
            } 
        },
        init: function($){
            console.log($.fn.jquery);
        }
    };
    myBkl.loadScript('http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js');
    myBkl.whenLoaded(myBkl.init);

})();

I use this bookmarklet builder to create the bookmarklet http://subsimple.com/bookmarklets/jsbuilder.htm

Obviously if the page already has jQuery loaded. The loading of the 1.3.2 script would overwrite the window.jQuery object on the page. I just wonder is there anyway to let 1.3.2 to load to another self named variable? Using jQuery.noConflict(true); ?

Was it helpful?

Solution

I suspect you've already seen all the caveats and understand you can move jQuery to another namespace:

//Completely move jQuery to a new namespace in another object.

var dom = {};
dom.query = jQuery.noConflict(true);

And that plugins probably won't work AND you must do all this before other scripts are loaded or used.

Good Luck / kinda curious to learn if this works for you~

OTHER TIPS

Yes. I got it work by this code:

    (function(){

    var myBkl = {
         jq: null,
         loadScript: function(src) {
            if(window.jQuery && window.jQuery.fn.jquery == '1.3.2'){
                return;
            }
            var s = document.createElement('script');
            s.setAttribute('src', src);
            s.setAttribute('type', 'text/javascript');
            document.getElementsByTagName('head')[0].appendChild(s); 
        },
        whenLoaded: function(callback){
            if (typeof(window.jQuery) !== 'undefined' && window.jQuery.fn.jquery == '1.3.2') { 
                myBkl.jq = window.jQuery.noConflict(true);
                callback(myBkl.jq); 
            } 
            else {
                setTimeout((function() {myBkl.whenLoaded(callback); }), 100);
            } 
        },
        init: function($){
            console.log($.fn.jquery);
            console.log(window.jQuery.fn.jquery);
        }
    };
    myBkl.loadScript('http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js');
    myBkl.whenLoaded(myBkl.init);

})();

When running "jQuery.noConflict(true);" The code that use the first jQuery version may break.
In some cases this, code doesn't even belong to you. You write a script, which is supposed to be added to pages and which uses jQuery, and you know nothing about the hosting page.
A hosting code may load its jQuery version, detected that it was loaded, start working with it, then wait (setTimeout) ,and then your code starts, do "jQuery.noConflict(true);" , and waits till it is loaded. While your code waits, the control may return to the hosting code which tries to run its jQuery and finds that it doesn't exist.

My suggestion, for this case, is to load the jQuery in a different new window, without removing it from the original one. Then, when it is loaded, use the "jQuery.noConflict(true);" on the new window to copy it to the original window. However the new jQuery object is actually running on the new window and its document. So when using the new jQuery the original window.document must be pass as the second parameter like this:

newJq("#elementInOriginalDocument", window.document).html("some text");

Following my implementation for this idea:

<html>
    <head>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js"></script>
    </head>
    <body>
        Test jQuery
        <br />
        <span id="hostScope">hostScope</span>
        <br />
        <span id="guestScope">guestScope</span>

        <script>
            (function(hostWin){
                    var myBkl = {
                            win: null,
                            doc: null,
                            jq: null,
                            loadScript: function(src) {
                                if (this.doc == null){
                                    var nAgt = navigator.userAgent;
                                    if ((verOffset=nAgt.indexOf("MSIE"))!=-1) {
                                        var iframe = document.createElement('iframe');
                                        iframe.id = "if1";
                                        iframe.src= window.location.href;
                                        document.getElementsByTagName('head')[0].appendChild(iframe);
                                        this.whenIEIFrameLoaded(src, 0);
                                    } else {
                                        var iframe = document.createElement('iframe');
                                        iframe.id = "if1";
                                        document.getElementsByTagName('head')[0].appendChild(iframe);
                                        setTimeout((function() {myBkl.whenIframeLoaded(src); }), 1);
                                    }
                                }
                            },
                            whenIframeLoaded: function(src){
                                var oIframe = document.getElementById('if1');
                                var newdocument = (oIframe.contentWindow || oIframe.contentDocument);
                                if (newdocument.document) {
                                    newdocument = newdocument.document;
                                }
                                var newwin = oIframe.contentWindow;

                                if (newwin.document.documentElement.innerHTML){
                                    newwin.document.documentElement.innerHTML = '<!DOCTYPE html><html><head></head><body>N</body></html>';
                                }
                                this.doc = newwin.document;
                                this.win = newwin;

                                var script = this.doc.createElement('script');
                                script.setAttribute('src', src);
                                script.setAttribute('type', 'text/javascript');

                                this.doc.getElementsByTagName('head')[0].appendChild(script); 
                                this.whenLoaded(this.callback, 0);
                            },
                            whenIEIFrameLoaded: function(src, times){
                                var oIframe = document.getElementById('if1');

                                if (oIframe && oIframe.contentWindow && oIframe.contentWindow.document && oIframe.contentWindow.document.body){
                                    var newdocument = (oIframe.contentWindow || oIframe.contentDocument);
                                    if (newdocument.document) {
                                        newdocument = newdocument.document;
                                    }

                                    var script = newdocument.createElement('script');
                                    script.setAttribute('src', src);
                                    script.setAttribute('type', 'text/javascript');

                                    newdocument.getElementsByTagName('head')[0].appendChild(script); 

                                    this.doc = newdocument;
                                    this.win = oIframe.contentWindow;
                                    this.whenLoaded(myBkl.callback, 0);
                                } else {
                                    if (times < 5000){
                                        times++;
                                        setTimeout((function() {myBkl.whenIEIFrameLoaded(src, times); }), 2);
                                    }
                                } 
                            },
                            whenLoaded: function(callback, times){
                                    if (this.win && this.win.jQuery && typeof(this.win.jQuery) !== 'undefined' && this.win.jQuery.fn.jquery == '1.3.2') { 
                                        myBkl.jq = this.win.jQuery.noConflict(true);
                                        callback(myBkl.jq);
                                    } 
                                    else {
                                        if (times < 5000){
                                            times++;
                                            setTimeout((function() {myBkl.whenLoaded(callback, times); }), 5);
                                        }
                                    } 
                            },
                            callback: function(loadedJq){
                                    hostWin.myJq = loadedJq;
                                    //console.log("callback: The loaded jQuery ver is " + loadedJq.fn.jquery);
                                    whenLoadedOut();
                            }
                    };
                    myBkl.loadScript('http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.js');
            })(window);

            function whenLoadedOut(){
                if (window.jQuery) { 
                    //console.log("Host jQuery ver (window.jQuery.fn.jquery) is " + jQuery.fn.jquery);
                    //console.log("guest jQuery ver (window.lpJq)  is " + myJq.fn.jquery);
                    $("#hostScope").html("The jQuery ver of host is " + jQuery.fn.jquery);
                    myJq("#guestScope", document).html("The jQuery ver of guest is " + myJq.fn.jquery);
                } 
                else {
                    setTimeout((function() {whenLoadedOut(); }), 2);
                } 
            }
        </script>
    </body>
</html>

Check this blog

You can use the method

$.noConflict(true);

to accomplish this. For example:

<script src="http://code.google.com/p/jqueryjs/downloads/detail?name=jquery-1.3.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
    //create this naming for Jquery 1.3.2 version
    var jQuery_1_3_2 = $.noConflict(true);
</script>
<script src="http://jqueryjs.googlecode.com/files/jquery-1.2.6.min.js" type="text/javascript"></script>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top