Clement Escoffier | bc69a4e | 2009-07-21 11:44:30 +0000 | [diff] [blame] | 1 | |
| 2 | /* |
| 3 | * Supersubs v0.2b - jQuery plugin |
| 4 | * Copyright (c) 2008 Joel Birch |
| 5 | * |
| 6 | * Dual licensed under the MIT and GPL licenses: |
| 7 | * http://www.opensource.org/licenses/mit-license.php |
| 8 | * http://www.gnu.org/licenses/gpl.html |
| 9 | * |
| 10 | * |
| 11 | * This plugin automatically adjusts submenu widths of suckerfish-style menus to that of |
| 12 | * their longest list item children. If you use this, please expect bugs and report them |
| 13 | * to the jQuery Google Group with the word 'Superfish' in the subject line. |
| 14 | * |
| 15 | */ |
| 16 | |
| 17 | ;(function($){ // $ will refer to jQuery within this closure |
| 18 | |
| 19 | $.fn.supersubs = function(options){ |
| 20 | var opts = $.extend({}, $.fn.supersubs.defaults, options); |
| 21 | // return original object to support chaining |
| 22 | return this.each(function() { |
| 23 | // cache selections |
| 24 | var $$ = $(this); |
| 25 | // support metadata |
| 26 | var o = $.meta ? $.extend({}, opts, $$.data()) : opts; |
| 27 | // get the font size of menu. |
| 28 | // .css('fontSize') returns various results cross-browser, so measure an em dash instead |
| 29 | var fontsize = $('<li id="menu-fontsize">—</li>').css({ |
| 30 | 'padding' : 0, |
| 31 | 'position' : 'absolute', |
| 32 | 'top' : '-999em', |
| 33 | 'width' : 'auto' |
| 34 | }).appendTo($$).width(); //clientWidth is faster, but was incorrect here |
| 35 | // remove em dash |
| 36 | $('#menu-fontsize').remove(); |
| 37 | // cache all ul elements |
| 38 | $ULs = $$.find('ul'); |
| 39 | // loop through each ul in menu |
| 40 | $ULs.each(function(i) { |
| 41 | // cache this ul |
| 42 | var $ul = $ULs.eq(i); |
| 43 | // get all (li) children of this ul |
| 44 | var $LIs = $ul.children(); |
| 45 | // get all anchor grand-children |
| 46 | var $As = $LIs.children('a'); |
| 47 | // force content to one line and save current float property |
| 48 | var liFloat = $LIs.css('white-space','nowrap').css('float'); |
| 49 | // remove width restrictions and floats so elements remain vertically stacked |
| 50 | var emWidth = $ul.add($LIs).add($As).css({ |
| 51 | 'float' : 'none', |
| 52 | 'width' : 'auto' |
| 53 | }) |
| 54 | // this ul will now be shrink-wrapped to longest li due to position:absolute |
| 55 | // so save its width as ems. Clientwidth is 2 times faster than .width() - thanks Dan Switzer |
| 56 | .end().end()[0].clientWidth / fontsize; |
| 57 | // add more width to ensure lines don't turn over at certain sizes in various browsers |
| 58 | emWidth += o.extraWidth; |
| 59 | // restrict to at least minWidth and at most maxWidth |
| 60 | if (emWidth > o.maxWidth) { emWidth = o.maxWidth; } |
| 61 | else if (emWidth < o.minWidth) { emWidth = o.minWidth; } |
| 62 | emWidth += 'em'; |
| 63 | // set ul to width in ems |
| 64 | $ul.css('width',emWidth); |
| 65 | // restore li floats to avoid IE bugs |
| 66 | // set li width to full width of this ul |
| 67 | // revert white-space to normal |
| 68 | $LIs.css({ |
| 69 | 'float' : liFloat, |
| 70 | 'width' : '100%', |
| 71 | 'white-space' : 'normal' |
| 72 | }) |
| 73 | // update offset position of descendant ul to reflect new width of parent |
| 74 | .each(function(){ |
| 75 | var $childUl = $('>ul',this); |
| 76 | var offsetDirection = $childUl.css('left')!==undefined ? 'left' : 'right'; |
| 77 | $childUl.css(offsetDirection,emWidth); |
| 78 | }); |
| 79 | }); |
| 80 | |
| 81 | }); |
| 82 | }; |
| 83 | // expose defaults |
| 84 | $.fn.supersubs.defaults = { |
| 85 | minWidth : 9, // requires em unit. |
| 86 | maxWidth : 25, // requires em unit. |
| 87 | extraWidth : 0 // extra width can ensure lines don't sometimes turn over due to slight browser differences in how they round-off values |
| 88 | }; |
| 89 | |
| 90 | })(jQuery); // plugin code ends |