/* * Supersubs v0.4b - jQuery plugin * Copyright (c) 2013 Joel Birch * * Dual licensed under the MIT and GPL licenses: * http://www.opensource.org/licenses/mit-license.php * http://www.gnu.org/licenses/gpl.html * * This plugin automatically adjusts submenu widths of suckerfish-style menus to that of * their longest list item children. If you use this, please expect bugs and report them * to the jQuery Google Group with the word 'Superfish' in the subject line. * */ /* * This is not the original jQuery Supersubs plugin. * Please refer to the README for more information. */ (function($){ // $ will refer to jQuery within this closure $.fn.supersubs = function(options){ var opts = $.extend({}, $.fn.supersubs.defaults, options); // return original object to support chaining // Although this is unnecessary due to the way the module uses these plugins. for (var a = 0; a < this.length; a++) { // cache selections var $$ = $(this).eq(a), // support metadata o = $.meta ? $.extend({}, opts, $$.data()) : opts; // Jump one level if it's a "NavBar" if ($$.hasClass('sf-navbar')) { $$ = $$.children('li').children('ul'); } // cache all ul elements var $ULs = $$.find('ul'), // get the font size of menu. // .css('fontSize') returns various results cross-browser, so measure an em dash instead fontsize = $(''), size = fontsize.attr('style','padding:0;position:absolute;top:-99999em;width:auto;') .appendTo($$)[0].clientWidth; //clientWidth is faster than width() // remove em dash fontsize.remove(); // loop through each ul in menu for (var b = 0; b < $ULs.length; b++) { var // cache this ul $ul = $ULs.eq(b); // If a multi-column sub-menu, and only if correctly configured. if (o.megamenu && $ul.hasClass('sf-megamenu') && $ul.find('.sf-megamenu-column').length > 0){ // Look through each column. var $column = $ul.find('div.sf-megamenu-column > ol'), // Overall width. mwWidth = 0; for (var d = 0; d < $column.length; d++){ resize($column.eq(d)); // New column width, in pixels. var colWidth = $column.width(); // Just a trick to convert em unit to px. $column.css({width:colWidth}) // Making column parents the same size. .parents('.sf-megamenu-column').css({width:colWidth}); // Overall width. mwWidth += parseInt(colWidth); } // Resizing the columns container too. $ul.add($ul.find('li.sf-megamenu-wrapper, li.sf-megamenu-wrapper > ol')).css({width:mwWidth}); } else { resize($ul); } } } function resize($ul){ var // get all (li) children of this ul $LIs = $ul.children(), // get all anchor grand-children $As = $LIs.children('a'); // force content to one line and save current float property $LIs.css('white-space','nowrap'); // remove width restrictions and floats so elements remain vertically stacked $ul.add($LIs).add($As).css({float:'none',width:'auto'}); // this ul will now be shrink-wrapped to longest li due to position:absolute // so save its width as ems. var emWidth = $ul.get(0).clientWidth / size; // add more width to ensure lines don't turn over at certain sizes in various browsers emWidth += o.extraWidth; // restrict to at least minWidth and at most maxWidth if (emWidth > o.maxWidth) {emWidth = o.maxWidth;} else if (emWidth < o.minWidth) {emWidth = o.minWidth;} emWidth += 'em'; // set ul to width in ems $ul.css({width:emWidth}); // restore li floats to avoid IE bugs // set li width to full width of this ul // revert white-space to normal $LIs.add($As).css({float:'',width:'',whiteSpace:''}); // update offset position of descendant ul to reflect new width of parent. // set it to 100% in case it isn't already set to this in the CSS for (var c = 0; c < $LIs.length; c++) { var $childUl = $LIs.eq(c).children('ul'); var offsetDirection = $childUl.css('left') !== undefined ? 'left' : 'right'; $childUl.css(offsetDirection,'100%'); } } return this; }; // expose defaults $.fn.supersubs.defaults = { megamenu: true, // define width for multi-column sub-menus and their columns. minWidth: 12, // requires em unit. maxWidth: 27, // requires em unit. extraWidth: 1 // extra width can ensure lines don't sometimes turn over due to slight browser differences in how they round-off values }; })(jQuery); // plugin code ends