I'm using superfish with the supersubs plugin plugin for my main navigation. That works perfect, except of one little problem. Some of the Submenu-ULs contain font-icons, that are embeded in i-tags, others don't. I think, the problem is, that the supersub plugin reads the width of the ULs on pageload and the icons aren't loaded at this point. So the script gets the wrong UL-width, which results in line break, due to the submenu being too small.
Now I'm trying to check, wheter a submenu-Ul contains a font icon or not, and want to add some extra width to the specific UL in case of an icon.
Below you see the supersubs plugin with my code in between, that is not working. The code is placed in the "each"-lop, that reads everey UL including it's childs and adds some CSS to the elements in order to get the ULs-width.
How do I determine, wheter an UL contains an i-tag?
Thanks
Lukas
// Initialize Supersubs Plugin
function supersubs_init(){
$(document).ready(function(){
$("ul.sf-menu").supersubs({
minWidth: 13,
maxWidth: 25,
extraWidth: 1
});
});
}
jQuery(function($){
$.fn.supersubs = function(options){
var opts = $.extend({}, $.fn.supersubs.defaults, options);
// return original object to support chaining
return this.each(function() {
// cache selections
var $$ = $(this);
// support metadata
var o = $.meta ? $.extend({}, opts, $$.data()) : opts;
// get the font size of menu.
// .css('fontSize') returns various results cross-browser, so measure an em dash instead
var fontsize = $('<li id="menu-fontsize">—</li>').css({
'padding' : 0,
'position' : 'absolute',
'top' : '-999em',
'width' : 'auto'
}).appendTo($$).width(); //clientWidth is faster, but was incorrect here
// remove em dash
$('#menu-fontsize').remove();
// cache all ul elements
$ULs = $$.find('ul');
// loop through each ul in menu
$ULs.each(function(i) {
var $s_ul = $ULs;
// cache this ul
var $ul = $ULs.eq(i);
// get all (li) children of this ul
var $LIs = $ul.children();
// get all anchor grand-children
var $As = $LIs.children('a');
// force content to one line and save current float property
var liFloat = $LIs.css('white-space','nowrap').css('float');
// remove width restrictions and floats so elements remain vertically stacked
// check if font icons are being displayed and add extra width
var emWidth = $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. Clientwidth is 2 times faster than .width() - thanks Dan Switzer
.end().end()[0].clientWidth / fontsize;
// add more width to ensure lines don't turn over at certain sizes in various browsers
// !!! THIS IS NOT WORKING !!!
if($($ULs + 'i[class^="icon-"]').length != 0){
emWidth += o.extraWidth + 1.25;
}
else{
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.css({
'float' : liFloat,
'width' : '100%',
'white-space' : 'normal'
})
// update offset position of descendant ul to reflect new width of parent
.each(function(){
var $childUl = $('>ul',this);
var offsetDirection = $childUl.css('left')!==undefined ? 'left' : 'right';
$childUl.css(offsetDirection,emWidth);
});
});
});
};
// expose defaults
$.fn.supersubs.defaults = {
minWidth : 13, // requires em unit.
maxWidth : 25, // requires em unit.
extraWidth : 2 // extra width can ensure lines don't sometimes turn over due to slight browser differences in how they round-off values
};
});