Reputation: 27
I have a small problem with the drop down menu on my site. (http://tornaia.com) When the mouse is just outside the menu, the menu dissapears, and I have to go back to the top. This can be a bit annoying when the menu has 3 or 4 levels. Is ther some way to put a delay on the menu so it doesn't go away at once?
Thanks you!
(Some time ago I tried to solve this issue in the Wordpress Forum, but we never made it. Anyway here is a link, so you can see what solutions we tried: http://wordpress.org/support/topic/how-to-delay-the-drop-down-menu-1?replies=10)
------EDIT (I inculde what I have tried here):-------------------
I found this file: wp-content --> themes --> rumput-hijau --> js --> methods.js
var $j = jQuery.noConflict();
$j(document).ready(function(){
/* Reponsive videos */
$j(".content-right").fitVids();
/* Reponsive menus */
$j(".nav").mobileMenu();
/* Drop down menus */
$j(".inside-primary-nav ul li ul").parent().addClass("arrow");
$j(".inside-primary-nav ul li").hover(function(){
$j(this).addClass("hover");
$j(this).find("ul:first").slideToggle("fast");
}, function(){
$j(this).removeClass("hover");
$j(this).find("ul:first").slideUp("fast");
});
});
So I tried changing the last line to
$j(this).find("ul:first").delay('900').slideUp("fast");
but that messed up the menu. Then I tried this
/* Drop down menus */
$j(".inside-primary-nav ul li ul").parent().addClass("arrow");
$j(".inside-primary-nav ul li").hover(function(){
$j(this).addClass("hover");
$j(this).find("ul:first").slideDown("slow");
}, function(){
$j(this).removeClass("hover");
$j(this).find("ul:first").slideUp("slow");
});
This code makes the menu slow down when it slides down, but the menu doesn't remain any longer when your mouse goes of it. So it's not what am looking for. I would like that the menu remains like one second (or something) after you leave it with the mouse. In that way, if you leave it without intension, it wont go away, and you can continue. So then I tried
$j(".inside-primary-nav ul li ul").parent().addClass("arrow");
$j(".inside-primary-nav ul li").hover(function(){
$j(this).addClass("hover");
$j(this).find("ul:first").slideDown("slow");
}, function(){
$j(this).removeClass("hover");
setTimeout(function() {
$j(this).find("ul:first").slideUp("slow");
}, 1000);
});
This code made the menu drop down slow the first time you hover it. The second time you hover it it seems like it has already been opened, so it just pops up. But the slide up dosen't change. When I take the mouse of the menu, it still dissapears.
----------------- EDIT: In the first code in the question I inserted the whole code of the file, not only the "/* Drop down menus */"-part
Upvotes: 2
Views: 4017
Reputation: 54639
Try this:
var hoverTimeout = null;
$j(".inside-primary-nav ul li").hover(function(){
$j(this).addClass("hover");
$j(this).find("ul:first").stop().slideDown("slow");
if(hoverTimeout){
clearTimeout(hoverTimeout);
}
}, function(){
$j(this).removeClass("hover");
hoverTimeout= setTimeout(function() {
$j(this).find("ul:first").stop().slideUp("slow");
}, 1000);
});
UPDATE
Ok so I think I finally got this to work, it was more complicated than I thought but I believe i found a solution, it may not be the best implementation but here it goes:
First you need to update your themes CSS file located in http://tornaia.com/wp-content/themes/rumput-hijau/style.css
, you have to replace all instances of li:hover
with li.hover
, this will make the sub-menus stay in position when the cursor is away from them.
Once that's done, update methods.js
, replace the current hover handler with this one:
var hoverTimeouts = {}; //Obj to store timeouts
$j(".inside-primary-nav ul li").hover(function(){
//Clear timeout if present
if(hoverTimeouts[$j(this).attr('id')]){
clearTimeout(hoverTimeouts[$j(this).attr('id')]);
delete hoverTimeouts[$j(this).attr('id')];
}else{
//Show sub-menu
$j(this).find(".sub-menu:first").hide().slideDown("slow");
}
$j(this).addClass("hover");
//Hide all other sub-menus in the level and clear their timeouts
$j(this).siblings().each(function(){
if(hoverTimeouts[$j(this).attr('id')]){
clearTimeout(hoverTimeouts[$j(this).attr('id')]);
delete hoverTimeouts[$j(this).attr('id')];
}
$j(this).removeClass('hover').find('.sub-menu').hide();
});
},function(){
//if item has sub-menu
if($j(this).find('.sub-menu').length){
//Store reference to menu item
var that = $j(this);
//Set timeout to remove after 1 sec and add it to obj
hoverTimeouts[$j(this).attr('id')]= setTimeout(function() {
that.removeClass("hover");
delete hoverTimeouts[that.attr('id')];
}, 1000);
}else{
//no sub-menu so just remove hover style
$j(this).removeClass('hover');
}
});
Note: Don't remove anything else from methods.js
, the last time the arrows disappeared because you probably remove the line where the class arrow
is added.
UPDATE 2
I think I found a cleaner solution, you still need to modify the CSS as I explained before, then you can add this to a new .js
file and include it in your site after methods.js
, no need to modify it
$(function(){
var hoverTimeout = null;
$j(".inside-primary-nav ul li").unbind();
$j(".inside-primary-nav ul li").hover(function(){
$j(this).siblings().each(function(){
$j(this).removeClass('hover').find('.sub-menu').hide();
$j(this).find('.hover').removeClass('hover');
});
$j(this).addClass("hover");
//Make sure parent style is ready to show new sub-menu
$j(this).closest('.sub-menu').css('overflow','visible');
$j(this).find(".sub-menu:first").stop().slideDown("fast");
}, function(){
if($j(this).find('.sub-menu:visible').length === 0)
$j(this).removeClass("hover");
});
$j(".inside-primary-nav > ul > li").hover(function(){
if(hoverTimeout){
clearTimeout(hoverTimeout);
}
},function(){
if($j(this).find('.sub-menu:visible').length > 0){
var that = $j(this);
hoverTimeout= setTimeout(function() {
that.removeClass('hover').find('.sub-menu').hide();
that.find('.hover').removeClass('hover');
}, 1000);
}
});
});
Upvotes: 2