116 lines
4.7 KiB
JavaScript
116 lines
4.7 KiB
JavaScript
/*
|
|
* 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 = $('<li id="menu-fontsize">—</li>'),
|
|
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
|