-
Notifications
You must be signed in to change notification settings - Fork 11
/
jquery.sooperfish.js
executable file
·134 lines (118 loc) · 4.43 KB
/
jquery.sooperfish.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
* SooperFish 0.3
* (c) 2010+ Jurriaan Roelofs - SooperThemes.com
* Inspired by Suckerfish, Superfish and Droppy
* Licensed GPL: http://www.gnu.org/licenses/gpl.html
*/
$.fn.sooperfish = function(op) {
var sf = $.fn.sooperfish;
sf.o = [];
sf.op = {};
sf.c = {
menuClass : 'sf-js-enabled',
isParent : 'sf-parent',
arrowClass : 'sf-arrow'
};
if ($.easing.easeOutOvershoot) { //set default easing
sooperEasingShow = 'easeOutOvershoot';
} else {
sooperEasingShow = 'linear';
};
if ($.easing.easeInTurbo) {
sooperEasingHide = 'easeInTurbo';
} else {
sooperEasingHide = 'linear';
};
sf.defaults = {
multiColumn : true,
dualColumn : 6, //if a submenu has at least this many items it will be divided in 2 columns
tripleColumn : 12, //if a submenu has at least this many items it will be divided in 3 columns
hoverClass : 'sfHover',
delay : 500, //make sure menus only disappear when intended, 500ms is advised by Jacob Nielsen
animationShow : {height:'show'},
speedShow : 600,
easingShow : sooperEasingShow,
animationHide : {height:'hide',opacity:'hide'},
speedHide : 200,
easingHide : sooperEasingHide,
autoArrows : true, //Adds span elements to parent li elements, projecting arrow images on these items to indicate submenus. I added an alternative image file with white arrows.
onShow : function(){}, //callback after showing menu
onHide : function(){} //callback after hiding menu
};
//Merge default settings with o function parameter
var o = $.extend({},sf.defaults,op);
if (!o.sooperfishWidth) {
o.sooperfishWidth = $('ul:first li:first', this).width(); //if no width is set in options try to read it from DOM
} else {
$('ul li', this).width(o.sooperfishWidth) //if width is set in invocation make sure this width is true for all submenus
}
this.each(function() {
//Check dom for submenus
var parentLi = $('li:has(ul)', this);
parentLi.each(function(){
if (o.autoArrows) { //Add autoArrows if requested
$('> a, > span',this).append('<div class="'+sf.c.arrowClass+'"></div>');
}
$(this).addClass(sf.c.isParent);
});
$('ul',this).css({left: 'auto',display: 'none'}); //The script needs to use display:none to make the hiding animation possible
//Divide menu in columns
//Set width override
if (o.multiColumn) {
var uls = $('ul',this);
uls.each(function(){
var ulsize = $('>li:not(.backLava)',this).length; //Skip list items added by Lavalamp plugin
if (ulsize >= o.dualColumn) {
if (ulsize >= o.tripleColumn) {
$(this).width(3*o.sooperfishWidth).addClass('multicolumn triplecolumn');
} else {
$(this).width(2*o.sooperfishWidth).addClass('multicolumn dualcolumn');
}
}
});
}
var root = this, zIndex = 1000;
function getSubmenu(ele) {
if (ele.nodeName.toLowerCase() == 'li') {
var submenu = $('> ul', ele);
return submenu.length ? submenu[0] : null;
} else if (ele.nodeName.toLowerCase() == 'span') {
var submenu = $(ele).parent().find('ul');
return submenu.length ? submenu[0] : null;
} else {
return ele;
}
}
function getActuator(ele) {
if (ele.nodeName.toLowerCase() == 'ul') {
return $(ele).parents('li')[0];
} else {
return ele;
}
}
function hideSooperfishUl() {
var submenu = getSubmenu(this);
if (!submenu) return;
$.data(submenu, 'cancelHide', false);
setTimeout(function() {
if (!$.data(submenu, 'cancelHide')) {
$(submenu).animate(o.animationHide,o.speedHide,o.easingHide,function(){ o.onHide.call(submenu);$(this).parent().removeClass('sf-open'); });
}
}, o.delay);
}
function showSooperfishUl() {
var submenu = getSubmenu(this);
if (!submenu) return;
$.data(submenu, 'cancelHide', true);
$(submenu).css({zIndex: zIndex++}).animate(o.animationShow,o.speedShow,o.easingShow,function(){ o.onShow.call(submenu);$(this).parent().addClass('sf-open'); });
}
// Use click/tap on touch devices and hover on normal devices.
if(!!('ontouchstart' in window) == false) {
$('li', this).unbind().hover(showSooperfishUl, hideSooperfishUl);
} else {
if ($('li > span', this).length > 0) {
$('li > span', this).unbind().toggle(showSooperfishUl, hideSooperfishUl);
}
}
});
};