So I've found some very helpful code here: http://codepen.io/slkav/pen/enHiI which I am using to create a pushdown megamenu. However, I'd like to convert the function to work on click, and close on subsequent click, rather than operate on hover as it currently does. I understand that opening the menu on click is as simple as changing mouseenter to click in the first function, but closing it again is tricky, especially since there are all these extra bits in there relating to hover timeout and such. Could anyone help me streamline this to work on click? I'm sure it's really simple but I'm just too inept to figure it out. Any help would be appreciated.
Here's the code as it stands:
// Megamenu push-down
// On li.main hover:
// 1. Give it 200 milliseconds before doing anything
// 2. Check if another megamenu is already visible (the user is quickly going from link to link). If so, show the content of the new megamenu without any slide animation and hide the previous one. If no megamenu is currently visible and the hovered li.main has a megamenu, slide it down
var $siteheader = $('#siteheader');
var $megamenu = $siteheader.find('nav li .megamenu');
var $pagecontent = $('#pagecontent');
var is_show = true;
// initiate timeout variables
hoverTimeout = "";
leaveTimeout = "";
$siteheader.find('nav li.main').click(function() {
var $thisMegamenu = $(this).find('.megamenu')
// stop any leaveTimeouts if they were triggered through guick back-and-forth hovering
clearTimeout(leaveTimeout);
// 1.
hoverTimeout = setTimeout(function() {
// 2. Another megamenu already open?
if( $megamenu.is(':visible') ) {
// if new hovered li has megamenu, hide old menu and show the new, otherwise slide everything back up
if( $thisMegamenu.length ) {
// stop any other hoverTimeouts triggered through guick back-and-forth hovering
clearTimeout(hoverTimeout);
$megamenu.filter(':visible').stop(true, true).hide();
$thisMegamenu.stop(true, true).show();
} else {
$megamenu.filter(':visible').stop(true, true).slideUp(500);
$pagecontent.stop(true, true).animate({ paddingTop: '0'}, 500);
}
} else {
if( $thisMegamenu.length ) {
// stop any other hoverTimeouts triggered through guick back-and-forth hovering
clearTimeout(hoverTimeout);
$thisMegamenu.stop(true, true).slideDown(500);
/* 16.5em is the set height of the megamenu + negative margin of nav ul */
$pagecontent.stop(true, true).animate({ paddingTop: '13em'}, 500);
}
}
}, 200);
});
// Leaving li item (if another li is hovered over quickly after, this is cleared)
$siteheader.find('nav li.main').mouseleave(function() {
clearTimeout(hoverTimeout);
leaveTimeout = setTimeout(function() {
if( $megamenu.is(':visible') ) {
$megamenu.filter(':visible').stop(true, true).slideUp(500);
$pagecontent.stop(true, true).animate({ paddingTop: '0'}, 500);
}
}, 200);
});
If your gonna have a click then you don't need any setTimeout. I've made the changes in the file. See below.
// Megamenu push-down
// On li.main hover:
// 1. Give it 200 milliseconds before doing anything
// 2. Check if another megamenu is already visible (the user is quickly going from link to link). If so, show the content of the new megamenu without any slide animation and hide the previous one. If no megamenu is currently visible and the hovered li.main has a megamenu, slide it down
var $siteheader = $('#siteheader');
var $megamenu = $siteheader.find('nav li .megamenu');
var $pagecontent = $('#pagecontent');
var is_show = true;
// initiate timeout variables
hoverTimeout = "";
leaveTimeout = "";
$siteheader.find('nav li.main').click(function() {
var $thisMegamenu = $(this).find('.megamenu')
// stop any leaveTimeouts if they were triggered through guick back-and-forth hovering
/*clearTimeout(leaveTimeout);
*/
// 1.
/*hoverTimeout = setTimeout(function() {*/
// 2. Another megamenu already open?
if( $megamenu.is(':visible') ) {
// if new hovered li has megamenu, hide old menu and show the new, otherwise slide everything back up
console.log($thisMegamenu.length);
if( $thisMegamenu.length ) {
console.log("in here")
// stop any other hoverTimeouts triggered through guick back-and-forth hovering
/* clearTimeout(hoverTimeout); */
$megamenu.filter(':visible').stop(true, true).slideUp(500);
$pagecontent.stop(true, true).animate({ paddingTop: '0'}, 500);
} else {
console.log("over here")
$megamenu.filter(':visible').stop(true, true).slideUp(500);
$pagecontent.stop(true, true).animate({ paddingTop: '0'}, 500);
}
} else {
if( $thisMegamenu.length ) {
// stop any other hoverTimeouts triggered through guick back-and-forth hovering
/* clearTimeout(hoverTimeout); */
$thisMegamenu.stop(true, true).slideDown(500);
/* 16.5em is the set height of the megamenu + negative margin of nav ul */
$pagecontent.stop(true, true).animate({ paddingTop: '13em'}, 500);
}
}
/* }, 200);*/
});
// Leaving li item (if another li is hovered over quickly after, this is cleared)
/*$siteheader.find('nav li.main').mouseleave(function() {
clearTimeout(hoverTimeout);
leaveTimeout = setTimeout(function() {
if( $megamenu.is(':visible') ) {
$megamenu.filter(':visible').stop(true, true).slideUp(500);
$pagecontent.stop(true, true).animate({ paddingTop: '0'}, 500);
}
}, 200);
});*/