jQuery Detector Overkill

With the ideas, help, and suggestions of some very smart folks, I’ve been able to put together a userscript that displays whether jQuery is used on the current page—along with version—and can also load jQuery into the current page by clicking the indicator if jQuery is not already present.

In early 2007, Paul Bakaus wrote a nifty userscript that displays the jQuery icon (jQuery Logo) at the bottom right hand side of the browser window when the page contains jQuery. (You need either Opera or the Greasemonkey plugin for Firefox to run userscripts.)

In a thread on the jQuery discussion group that (re)announced Paul’s userscript, Karl Swedberg suggested putting the version of jQuery in the image’s title attribute so it would show as a tooltip when you hover over it. As I am curious about when each site started using jQuery and what capabilities they have available on their site, I thought that was a fantastic idea. So, I copied Paul’s detector script to my own server, and added in Karl’s suggestion (modifying my userscript to point to my modded detector script).

I had been (and am still) having some problems with the version tooltip showing on my home browser–some plug-in or configuration issue, no doubt–so I cobbled together something that would display the page’s jQuery version in a div when I clicked on the icon.

Now, on a separate track, Karl had talked about how to create a jQuery bookmarklet that would insert jQuery into pages that do not have it, in order to have jQuery’s power on the console in Firebug or Dragonfly–or slightly more painstakingly with “javascript:” statements in the address bar for Internet Exploder and Safari (does Safari have its own console?). I’ve been using and loving it ever since I found it.

Karl recently wrote about an updated jQuery bookmarklet that has things like a spiffy div that pops up and tells you what it’s doing. When I saw that and thought about the display-on-click that I’d added to my jQuery Detector, I just knew that these were two great tastes that had to, er, play golf together.

So, here is the “debug” version of the script, i.e., with line breaks and long(er) variables names:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
(function() {
  var version=0.3, //cheaply find version when compressed
    b=document.getElementsByTagName('body')[0],
    el=document.createElement('div'),
    img = document.createElement('img'),
    els = el.style, ims = img.style,
    //"jquery is present" image
    jqimg='http://jquery.com/images/favicon.png';
 
  // style info div
  els.position='fixed';
  els.bottom='2px';
  els.right='20px';
  els.width='200px';
  els.height='24px';
  els.margin='0 auto 0 auto';
  els.padding='5px 10px 5px 10px';
  els.backgroundColor='#c33';
  els.color='#fff';
  els.fontSize='8pt';
  els.textAlign='center';
  els.display='none';
 
  // style jquery detector icon
  ims.position='fixed';
  ims.bottom='2px';
  ims.right='2px';
  ims.zIndex='5';
  ims.cursor='pointer';
  ims.border='0';
 
  b.appendChild(img);
  b.appendChild(el);
 
  // function overhead in order to rebind click event after loading jQuery
  // showJq(): img.click = display version of jQuery currently loaded
  function showJq() {
    var jq=jQuery, v = jq.fn.jquery;
    //"if" protects jquery.com from needless rechecking
    if(img.src!=jqimg) img.src=jqimg;
    img.title=v;
    el.innerHTML='Using jQuery v'+v;
    jq(img).click(function(){
      els.display='block';
      window.setTimeout(function() {
        jq(el).fadeOut('slow');
      }, 1000);
    });
  }
  //jquery exists; display version on icon click
  if (typeof jQuery != 'undefined') {
    showJq();
  //no jquery; show bland icon and load jquery on click
  } else {
    img.src='http://jquery.com/images/ics.png';
    img.title='Load jQuery';
    img.onclick=function(){ //todo: rebind click event to above
      var s=document.createElement('script');
      s.setAttribute('src','http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js');
      document.getElementsByTagName('head')[0].appendChild(s);
      var i = 0;
      // loadJQuery(): recursive calls until jQuery finishes loading
      function loadJQuery() {
        el.innerHTML='jQuery Loading...';els.display='block';
        if (++i < 10 &#038;& typeof jQuery == 'undefined') {
          window.setTimeout(loadJQuery, 50);  //recheck every x milliseconds
        } else if (i >= 10){    //don't try rechecking more than y times
          el.innerHTML='Load jQuery failed<br/>(try again?)';
        } else {    //finished loading; show version and fade out
          img.onclick=showJq; //rebind to just show version
          el.innerHTML='jQuery loaded, v'+jQuery.fn.jquery;
          img.src=jqimg;  //reset img url to jquery icon
          window.setTimeout(function() {
            jQuery(el).fadeOut('slow');
          }, 1000);
        }
      }
      loadJQuery();   //start loading jquery
    };
  }
})();

Once that’s done, all that’s left is to churn this (much heavier than Paul’s original) script through the YUI Compressor to cut its size down a bit. I also turned on compression for my scripts directory to get even more mileage out of it.

I have not yet gotten this working in Opera 9.5x, though Paul’s original script worked fine in 9.2x.

Each of the resulting scripts are available below:

Can you find problems or think of improvements—or give me tips on why I’ve broken it in Opera?

About pyrolupus

Writer, father, teacher, programmer, performer. And I make some mean pancakes, too.
This entry was posted in JavaScript, jQuery, userscripts and tagged , , . Bookmark the permalink.

One Response to jQuery Detector Overkill

  1. Excellent post! Nice idea to combine the two scripts.

    Safari 3.1 does have a console. You can use it once you’ve enabled the Develop menu (Preferences > Advanced tab). They call it an “Error Console” but it can be used for more than just error tracking.

    (btw, I had to disable JavaScript in order for your comment submission to work.)