views:

29

answers:

2

Hi, I'm creating a bookmarklet and everything was going ok. I had a function that loads jQuery asynchronous if the page didn't have it and then load my script or load my script directly if the page had jQuery.

Then I try to use the delegate function which is only available in jQuery 1.4.something. I can check the jQuery version with $().jquery but then if i load jQuery i have jQuery twice and events executes twice.

Is there a way to remove the previous loaded jQuery and then load the new version that I need?

+1  A: 

There is, but you'll be breaking the page when you do so, so I highly recommend not doing this. To remove jQuery itself:

 jQuery.noConflict(true);

This is just to show it can be done (though it doesn't remove all the effects it had), in your case I would not do this, what you're doing will really break the webpage your bookmarklet's running on.

Instead, consider if your bookmarklet needs the latest jQuery API, would a version behind fit all your needs? If so then use that, even if it's a bit less efficient, so it works whether the page has a slightly older version or not.

Nick Craver
@Nick, I'd edit, but I'm not entirely sure if I'm just missing the intent of your advice: " **I would not do this**, you're doing to really... "
David Thomas
@David - ...not sure what I was smoking there, thanks!, and updated :)
Nick Craver
@Nick, that does make more sense. And I'm glad I didn't edit, since I was half-sure it was just a d-for-g typo. =)
David Thomas
+1 for not doing this. jQuery's a big intrusive framework and in a bookmarklet you should be as light-touch as possible. You're a guest on a third-party page and you shouldn't make a nuisance of yourself by loading or changing major frameworks. Is your bookmarklet so complex you really can't do without `delegate()` (what about using `live()`?). Is your bookmarklet so complex you really can't do without jQuery period?
bobince
@bobince - +1 - I can't agree more on a time and place for things, this seems very, *very* heavy for a bookmarklet, and changing the framework on a page you're a guest in...I can't imagine a valid case for that either, nothing but trouble can come of this IMO.
Nick Craver
A: 

It is possible to move jQuery to another namespace.

//Completely move jQuery to a new namespace in another object.
var dom = {};
dom.query = jQuery.noConflict(true);

Here is some slightly altered code from another question, the asker was able to get it working for the exact same usage as you, a bookmarklet.

/* I have attempted to change the code to check for the 1.4.x and if its not then  
   load the latest version of jQUery.  */ 
    (function(){

        var myBkl = {
                 jq: null,
                 loadScript: function(src) {
                        if(window.jQuery && window.jQuery.fn.jquery.indexOf('1.4') >= 0){
                                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.indexOf('1.4') >= 0) { 
                                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/jquery.min.js'); //this will load the latest version from google cdn
        myBkl.whenLoaded(myBkl.init);

})();

Original Source Reference: http://stackoverflow.com/questions/613808/is-it-possible-to-load-multiple-different-version-of-jquery-on-the-same-page

The other option for you if you must do this, (after finding that you can't rewrite your bookmarklet without .delgate() as others have suggested) it is possible to have multiple versions of jQuery on the same page. look below:

if (typeof jQuery == ‘undefined’) {
    appendLatestJQuery();
}
else {
    jQVersion = $().jquery;
    versionArray = jQVersion.split(‘.’);
    if (versionArray[1] < 4) {
        appendLatestJQuery();
    }
    else {
        runthis();
    }
}

function appendLatestJQuery() {
    var jQ = document.createElement('script');
    jQ.type = 'text/javascript';
    jQ.onload=runthis;
    jQ.src = 'http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js';
    document.body.appendChild(jQ);
}
function runthis() {
    var $j = jQuery.noConflict(true);

    //now use $j for your code here

}
Moin Zaman
You shouldn't copy another answer, or post just a link to another question *as* your answer either.
Nick Craver
I don't think I've done either. I added what I think needs changing for this question. Look closer. But what is the best thing to do in this case?
Moin Zaman
@Moin - The question isn't asking about moving to another namespace, and you're not including a version of jQuery that the author needs either, 1.3.2 doesn't have delegate...you've just just copied another answer, and it still doesn't answer *this* question.
Nick Craver
@Nick: the end result is a solution to the problem of having one version of jQuery already on the page and how to use another version (becaause as you've pointed out, removing the existing version could break the page). I suggest you read the other question closely, then read my answer, esp the comment at the top of the referenced code from the other question.
Moin Zaman
I've updated the code to be more specific to this question
Moin Zaman