Below is a script with a few bugs and I am trying to work out the kinks. The main bug is a confusion or mix-up between currently selected(hovered) items' sub-menus and previously selected sub-menus.
jQuery(document).ready(function($) {
$("ul.menu > li").hover(
function() {
$(this).find("ul.sub-menu").stop().animate({
height: 'toggle',
opacity: 'toggle'
});
}
);
});
The bug doesn't appear on the initial hover of each parent item but seems to only happen, as can be seen from this fiddle, if hovered over the 2nd parent item, then hover the 1st parent, and then quickly hover into 1st sub-menu, you will see the desired sub-menu disappear, and the previously selected sub-menu reappears. Also, I should also add that if hovered over the 3rd parent item, then hover over the 2nd parent, and then quickly hover into 2nd sub-menu, you will again see the undesired effects, or bug.
Another less detailed bug or glitch is that after the right combination or amount of random hovers 1 of 3 sub-menus permanatly disappears. Basically, the script is very unstable; how can I make this script a rock solid UI? How can these bugs be eliminated to ensure the best UX? Thanks.
Problem is that you are catching the second sub menu while it is still visible and it counts as hovering it once again.
You can solve this pretty easily by updating the z-index for the sub-menu corresponding to the hovered element:
$("ul.sub-menu").css('z-index', 1);
$(this).find("ul.sub-menu").css('z-index', 2).stop()...
http://jsfiddle.net/pF8wZ/6/
Related
My e-commerce store requires three tier menu item to achieve the multi-column megamenu appearance that I want, and although its a bit weird I have found a workaround on desktop by simply hiding the "middle" menu item as "shown" here by the red box (as in there are menu items there, but they are display none).
This is honestly fine, as I hover over the parent menu item, and then only see the li menu items. However my issue is actually on mobile, where the expanding of the top menu item requires a click, and then I need to click a second time to expand the "middle" menu item as you can see in the screenshot below:
There is an event attached to both "caret" clicks, and that is:
function(e) {
e.target.closest("li").classList.toggle("dropdown-open"), e.preventDefault()
}
This attaches an event to the menu item as shown in this screenshot:
..and that allows the submenu to appear below "Weighing Categories" like this:
So my goal (on the mobile viewport) is to show all the submenu items (with the exception of the middle one, in this case "weighing categories") when the categories caret is clicked. I have tried a CSS approach (which is what the dropdown-open class is basically adding), but this results in it always showing (whereas I still want to keep the first click, just not the second click requirement).
body .main-navigation ul.menu li.menu-item-has-children > .sub-menu-wrapper { position: inherit; left: auto; opacity: 1; transform: translateX(0); }
I have also tried multiple variations of using JS to insert a class, and I think this is on the right track, but missing something lol.. I must admit that my JS is poor, mainly trying examples I have found during my research and adapting them.
jQuery("nav-menu-item-1247 .caret").click(function() {
jQuery("#nav-menu-item-6721").addClass( "dropdown-open");
});
The above (and note that it is not working) was supposed to add "dropdown-open" proactively to the weighing categories menu item ("6721") when the top menu item (the "1247" is the "categories" one) is clicked. Perhaps the prevent default in the default JS is blocking it, I am not sure and do not have the skill to troubleshoot it lol.
I would really appreciate some help, been fighting with this for almost 4 hours and I am probably doing something stupid lol. I can share the URL if needed, it is just locked behind a user/pass before it goes live, but I can temporarily remove it.
Thanks :)
I'm trying to create an effect similar to the navigation on this site: http://rogwai.com/. I'm fairly close as you can this in this jsFiddle.
It's working fine if you hover into one li at a time (i.e. from the bottom). If however, you slide horizontally through each list item the 'follower' returns to the active position or slides of the end after each item that's hovered over. Instead it should follow the mouse.
Looking at the code executed on hover out this is completely understandable. What I can't get my head around is how to make it only return to the active position or slide off the end when the mouse completely leaves the menu.
Hopefully that makes sense - you should see the problem straight away from the jsFiddle.
Thanks in advance.
What you can do is add the mouseenter part to the li as you have it, but put the mouseleave part on the entire ul. This way, the leave will only fire when you mouse out of the entire ul.
http://jsfiddle.net/YZr5b/6/
$('nav.block-system-main-menu ul li:not(.follower)').mouseenter(function() {
followerMove($(this));
});
$('nav.block-system-main-menu ul').mouseleave(function(){
followerMove($active);
});
Note, if you are really using jquery 1.2.6 (quite old), you will need to modify this a bit as mouseenter and mouseleave do not exist.
The following jsfiddle demonstrates the problem. In Firefox, hover over 'highlight stories' and try to select from the second drop-down: the containing ul animates closed and it is impossible to select an option. It is also possible to get into a flickering loop by selecting from the top select box and moving the mouse down slightly.
I can remove the mouseleave event by doing something like this:
$('.selector').click(function(){
$('nav ul li').unbind('mouseleave');
});
But this obviously prevents the hover animation from firing correctly. Can anyone suggest a more elegant solution?
http://jsfiddle.net/codecowboy/mDUa9/8/
Here's my attempt: http://jsfiddle.net/rPe9r/
$('nav ul li').hover(function() { // mouse enter
$('ul', this).slideDown(100);
}, function() { // mouseout
var container = $("ul", this);
// Hide popup if dropdown menu is not active
if (!container.hasClass("dropdown-active")) {
container.slideUp(100);
}
});
$("nav select").bind("focus", function() {
$(this).closest("ul").addClass("dropdown-active");
}).bind("change focusout", function() {
$(this).closest("ul").removeClass("dropdown-active");
});
The code tries to determine when a select box is active and supresses the slideUp of the container on mouseleave when any of the select boxes are active.
I've only tested this in Firefox, and I suspect this may be too simplistic and may not cover all uses cases (for instance, when user selects an already selected item from the dropdown which will not trigger the change event). Further testing/tweaking may be required.
Perhaps a more robust method would be to dynamically scale the height of the container when the dropdown box expands such that the mouse does not leave the container when users navigate the dropdown menu. Of course, the difficulty here is to determine the size of a select dropdown menu in a portable way.
A possible workaround would be to use one of the many jquery plugins available out there that replaces <select> with a <div>. This gives you more flexibility in styling your dropdown menus, and more importantly, allow you to tweak your css such that the containing div is scaled automatically when the dropdown menu is expanded.
Just a thought.
I'm trying to create some drop down elements with CSS and jquery. Here's what I'm trying to achieve:
When mouse hovers over a particular word in a sentence the background
colour of the word is altered and a drop down appears with a few
options (using same background colour).
The background colour of the original highlighted word should hold
when hovering over the options below.
Upon leaving the drop down it should return to hidden and the
original word should return to a background color of transparent.
The solution I have at the moment doesn't work perfectly. Hovering sometimes causes the drop down to flicker a bit. I'm wondering if anyone could suggest some better approaches?
I think what I've done is a bit of a hack really. I'm unsure how to select the specific li element that the user hovers over originally so I can alter the bg colour of that particular element (without specifically assigning IDs to every parent li). So instead I simply change all li elements to transparent upon leaving the dropdown and then have to change all elements to the blue bg colour if the word is highlighted again. Also when hovering over sub items I'm effectively changing the bg colour each time which also doesn't seem the best way to do it.
Here's the javascript:
$('#nav li').hover(
function () {
$(this).css('background-color', '#A7B7FF'); // to set parent item to blue
$('ul', this).css('background-color', '#A7B7FF'); // set sub items to blue
//show its submenu
$('ul', this).css('z-index', '600'); // so it overlaps other drop down below
$('ul', this).slideDown(100);
},
function () {
//hide its submenu
$('ul', this).slideUp(100,
function() {
$('li').css('background-color', 'transparent'); // callback so parent item returns to transparent
}
);
}
);
For a full example look here: http://jsfiddle.net/A4r2m/1/
Many Thanks
I throttled the hoverleave for 500 milliseconds, so it won't flicker. This also means it takes 500 milliseconds for the menu to disappear after the user has left the area so user can accidentally leave the area for a bit and then come back and it won't have to animate all over again.
edit: I needed to add cancel to the throttled hoverOut.
http://jsfiddle.net/A4r2m/4/
This is probably a simple problem I'm having, but for the life of me, I can't seem to figure it out. If any of you could help me with this, I would be much obliged.
I'm using JQuery to make a menu appear when a user hovers over a certain div. The menu will be displayed on the top left of the div.
I got this to work, but when I try to click on a menu item of the div that appeared, the div disappears again, because the mouse is technically not over the div, but over the menu.
In the example below, "#blockMenu" is the menu that dynamically appears. I fade the current div ($this)) out a bit, to emphasize the menu as well.
I use the following code to make this happen:
$("div.editable").hover(function () {
$(this).fadeTo(500, 0.25);
$('#Menu').css("position", "absolute");
$("#Menu").css("top", $(this).offset().top);
$("#Menu").css("left", $(this).offset().left);
$("#Menu").css("zIndex", "10000");
$('#Menu').show();
}, function (e) { // on mouseout
$(this).fadeTo(500, 1);
$("#Menu").hide();
});
I want the menu to disappear when the cursor leaves the div, while the div remains faded out when the cursor is on the menu. When the cursor leaves the menu AND the div at the same time, the div should fade back in and the menu should disappear.
Does anyone have an idea of how I could edit my code to make this work correctly?
Thank you very much for any help you can give me.
Just use the :hover pseudo class, that's likely to help the situation. You'll lose animation effects, but it could sure make things easier, and take javascript out of the picture
Add a hover function for the menu and set some state when the mouse is hovering over the menu and only take the menu down if the mouse is not over the div AND not over the menu.