Just noticed something. After pigging around with my custom click menu, I thought I'd take another look at the Superfish plugin that runs the current hover menus. There's room for some optimisation in there (IIRC it was originally written for jQ 1.2.x).
1/ For a start, there's no longer any need to set a hover class here (or anywhere else):
if (o.$path.length && $$.parents(['li.',o.hoverClass].join('')).length<1){over.call(o.$path);}
The hover class was only ever included to provide li:hover support for IE<7. Since we don't care about that any more, any code related to the hover class can be removed. Not only is this good for shortening the js, but it also gets rid of some stuff from the css (because if the hover class is being applied, the css needs to deal with it, otherwise things don't work).
2/ It would be good to figure out how to get rid of this last line related to the (deprecated) add arrow stuff. Better to add arrows (if wanted) via css.
// This next line is essential, despite the other code for arrows being removed.
// Changing the next line WILL break hoverIntent functionality. Very bad.
addArrow = function($a){$a.addClass(c.anchorClass)};
3/ More hover class poo, and IIRC using li:has(ul) is not the fastest way of handling that one. Would have to check.
Also, I have NFI what the breadcrumbs class (bcClass) was supposed to be for, but I can't recall it ever doing anything useful.
$(this).addClass([o.hoverClass,c.bcClass].join(' '))
.filter('li:has(ul)').removeClass(o.pathClass);
4/ There's no need to allow for disabling hoverIntent. IMO, that setting is just bloat.
$('li:has(ul)',this)[($.fn.hoverIntent && !o.disableHI) ? 'hoverIntent' : 'hover'](($.fn.hoverIntent && !o.disableHI) ? (h) : (over,out)).each(function() {})
.not('.'+c.bcClass)
5/ I have a suspicion that none of the following are really needed (only a suspicion at this stage).
sf.c = {
bcClass : 'sf-breadcrumb',
menuClass : 'sf-js-enabled',
anchorClass : 'sf-with-ul',
};
6/ As mentioned, hover class and disable hoverIntent could be dropped here.
sf.defaults = {
hoverClass : 'sfhover',
pathClass : 'current',
pathLevels : 1,
delay : 600,
animation : {opacity:'show', height: 'show', width: 'show'},
speed : 200,
disableHI : false, // Leave as false. True disables hoverIntent detection (not good).
7/ This pile of stuff could be simplified quite a bit.
$.fn.extend({
hideSuperfishUl : function(){
var o = sf.op,
not = (o.retainPath===true) ? o.$path : '';
o.retainPath = false;
var $ul = $(['li.',o.hoverClass].join(''),this).add(this).not(not).removeClass(o.hoverClass)
.find('>ul').hide().css('opacity','0');
o.onHide.call($ul);
return this;
},
For a start, cutting out the IE<7 hover class is going to significantly de-bloat this section.
The other point is the hide() operation. Originally the code in that line read like this:
.find('>ul').hide().css('display','none');
I changed that because display: none; will bork things for screen readers, but of course at the time I didn't realise that .hide() did exactly the same thing. So the original code effectively said "set display: none; by using the slowest method, then set display: none; again".
Currently it effectively says "set display: none; by using the slowest method, then set opacity: 0;".
Methinks that perhaps this is not the best way of coding it. A better option would be:
.find('>ul').css('opacity','0');
Fewer operations, uses the fastest one, and better for a11y.
8/ More hover class poo here.
showSuperfishUl : function(){
var o = sf.op,
sh = sf.c,
$ul = this.addClass(o.hoverClass)
There are probably a few other things that could be tweaked, but those are the obvious ones.