Colourblind

Welcome to Colourblind.

This is the personal web space of Tom Milsom. As much as possible everything is free (as in speech and as in beer).


Make text: Smaller Bigger

You So Crazy - a silly, paranoia-inducing jQuery plugin

Posted by Tom on 02/05/2011 18:56:39

Have you ever wanted a jQuery plugin that causes your users to question their sanity? Then look no further!

You So Crazy inserts phrases into the paragraphs of an HTML document, which then disappear when they are scrolled out of view, only to reappear in a different place.

Demo

And here, as always, is the source:

   1:  (function($){
   2:      $.you_so_crazy = function(customPhrases, options) {
   3:      
   4:          var phrases = [
   5:              'feed me a stray cat'
   6:          ];
   7:          var settings = {
   8:              'highlight'     : false
   9:          };
  10:          
  11:          if (options)
  12:              $.extend(settings, options);
  13:          if (customPhrases)
  14:              phrases = phrases.concat(customPhrases);
  15:          
  16:          var currentElement = null;
  17:          var spotted = false;
  18:    
  19:          $(window).scroll(function() {
  20:              if (currentElement)
  21:              {
  22:                  if (element_on_screen(currentElement))
  23:                  {
  24:                      if (spotted)
  25:                      {
  26:                          select_element();
  27:                          spotted = false;
  28:                      }
  29:                  }
  30:                  else
  31:                  {
  32:                      if (!spotted)
  33:                          spotted = true;
  34:                  }
  35:              }
  36:          });
  37:          
  38:          var select_element = function() {
  39:          
  40:              if (currentElement)
  41:                  currentElement.remove();
  42:   
  43:              var target = null;
  44:              while(target == null)
  45:              {
  46:                  var paragraphs = $('p');
  47:                  var index = Math.floor(Math.random() * paragraphs.length);
  48:                  target = $(paragraphs[index]);
  49:                  
  50:                  if (element_on_screen(target))
  51:                      break;
  52:                      
  53:                  target = null;
  54:              }
  55:              
  56:              var tokens = target.html().split(' ');
  57:              var strIndex = Math.floor(Math.random() * tokens.length);
  58:              var phraseIndex = Math.floor(Math.random() * phrases.length);
  59:              var finalPhrase = '<span class="psycho42"' 
  60:                  + (settings.highlight ? ' style="background-color: #f00;">' : '>') 
  61:                  + phrases[phraseIndex] + '</span>';
  62:              tokens.splice(strIndex, 0, finalPhrase);
  63:              target.html(tokens.join(' '));
  64:              currentElement = target.find('span.psycho42');
  65:          };
  66:          
  67:          var element_on_screen = function(element)
  68:          {
  69:              var screen_position = element.offset();
  70:              screen_position.top -= $(document).scrollTop();
  71:              screen_position.left -= $(document).scrollLeft();
  72:              var windowSize = { 'left': $(window).width(), 'top': $(window).height() }
  73:              
  74:              return screen_position.top + element.height() < 0 
  75:                  || screen_position.left + element.width() < 0
  76:                  || screen_position.top > windowSize.top 
  77:                  || screen_position.left > windowSize.left;
  78:          }
  79:          
  80:          select_element();
  81:      };
  82:  })(jQuery);

This is a strong contender for the title of most pointless code I've ever written, but I had a spare hour and felt it was about time I added my own contribution to the swath of jQuery plugins out there.

Comments (0)

Dynamic Section Numbers and Table of Contents with jQuery

Posted by Tom on 25/10/2009 16:18:48

At work I'm thinking of moving our specs and other documentation over to HTML. We are, after all, well acquianted with the Tubular Interwebs.

One of the things that I miss whenever it's not present in these kinds of docs are section numbers and a table of contents, but maintaining them can be a pain in the arse. You add a new section and then all your subsequent sections needs to shuffle down to accomodate it. What we need is the equivalent of BBC Basic's RENUMBER command, and I never thought I would say that ever again.

But why not generate it dynamically? We have the tools, and we have the talent. Also, we have jQuery.

function NumberHeadings(list, parent, prefix)
{
    if (list.length == 0)
        return '';

    var menu = '';
    var level = parseInt(list[0].tagName.substr(1));
    var index = 0;
    
    menu += '<ul>\n';
    list.each(function() {
            var current = $(this);

            if (parent != '' && current.prevAll('h' + (level - 1)).eq(0).html() != parent)
                return '';
            
            var number = prefix  + (++ index) + '.';
            var content = number + ' ' + current.html();
            
            current.html(content);
            current.before('<a name="' + number + '"></a>');
            menu += '<li><a href="#' + number + '">' + current.html() + '</a></li>\n';
            
            menu += NumberHeadings(current.nextAll('h' + (level + 1)), content, number);
        });
    menu += '</ul>\n';
    
    return menu;
}

This function takes as it's input a list of h tags (h2, h3, whatever), the contents of its 'parent' heading tag and the prefix of the numerical prefix of the new section. But you can safely ignore most of that. The easiest way to use it is like this:

$(document).ready(function() {
        $('#Menu').html(NumberHeadings($('h2'), '', ''));
    });

Now as long as you make sure your headings use H tags and are nested correctly like you should be doing anyway, you slacker then that script will number all of your headings and provide a table of contents with anchor links to each section. The only other caveat is that the prevAll function must return items in the reverse of the order that they appear in the DOM (as it does currently) or things will break.

And here it is working.

In a largely irrelevant asside, I'm sure the first version of this that I wrote was neater, but since that version only existed on my laptop, which I left on the train last week and has never been handed in, we'll never know. Also there's some tossbag wandering around London with my laptop and, while I take some solace in the fact that it had Vista on it, I hope their nipples drop off.

Comments (0)