jQuery menu effect gone wrong - javascript

I am seeking for a way to fade a submenu in a list-ordered navigation as I want it to fade:
There is always an active menu item - and if the active menu item is in the submenu - also an active menu parent. So, at init the submenu with an active current item or current parent item should be visible. If I hover an other menu item, its submenu will fade in, the active one fades out. After leaving the whole menu, the active submenu fades in again. Plus, I used the jQuery plugin hoverIntent (http://cherne.net/brian/resources/jquery.hoverIntent.html) to give a timeout for each hover action.
This is what I got so far, but it's really buggy. For some reasons, submenus are sometimes just disappearing completely, also when hovering two items without leaving the navigation, two submenus overlap. Does anyone have an idea or tip for me? =) Please see a demo HERE: http://jsfiddle.net/BQuPz/

Problems with CSS: It's best not to play with display:none and opacity yourself, leave it up to jQuery and use the proper functions for fadeIn() and fadeOut().
Instead of putting display:block; float:left; on the menu's <li> elements, you should use display:inline-block. If you float the <li>s, that effectively tears them out of their parent container, leaving the ul with zero size, hence it is impossible to listen to mouseleave events unless you explicitly set its size.
Problems with code: In the hoverIntent plugin, timeout might not be what you're looking for. Timeout automatically fires the out event after a certain amount of time. To delay the hover effect, use sensitivity and interval instead. Check out the documentation page.
If you apply the above fixes, the only events needed are hoverIntent's over and the main navigation's mouseleave. The over event fades in the current submenu and fades out the rest, the mouseleave fades in the active submenu when the user hovers off the navigation. Look at your modified jsfiddle demo: http://jsfiddle.net/BQuPz/4/
// Hide inactive ones
$('#main-nav > li:not(.current-menu-parent) .sub-menu').hide();
// What to do when hovering over a menu item
$("#main-nav > li").hoverIntent({
over: function(){
// Find the hovered menu's sub-menu
var $submenu = $(this).find('.sub-menu');
// Stop the animation and fade out the other submenus
$('.sub-menu').not($submenu).stop(true,true).fadeOut(260);
// Fade in the current one
$submenu.fadeIn(260);
}
});
// What to do when user leaves the navigation area
$('#main-nav').mouseleave(function(){
// Fade out all inactive submenus
$('#main-nav > li:not(.current-menu-parent) .sub-menu').fadeOut(260);
// Fade in the active one
$('.current-menu-parent .sub-menu').fadeIn(260);
});

Instead of using animate in $(this).find("ul").animate({'opacity': '1'}, 250);
I would have used fadeIn and fadeOut functions with callbacks. Then you're sure your fadeIn animation begins after the fadeout ends
element.fadeOut(250,function(){otherElement.fadeIn(250)})

Related

Slick Slider js not recentering with scrollSpy

So I created a horizontal mobile Menu navigation with Slick Slider and also added a scroll Spy to add active class to the li when scrolling passed categories.
So far it looks great. Here is the link, make your browser be mobile size (because it is only visible on small screens)
And visit http://www.2017.jukeboxburgers.com/menu click on the " Explore the Food... " button, and swipe.
When you click in the nav it works well, the li gets centered, but now if you scroll down some more until you pass a few categories, and then click the "explore the food" button again, the current category you scrolled too is not centered.
Is there an event listener for something like this? Or a way to make it recalculate the li.active and center it??
So was able to make it work!
So my scrollSpy puts a class of .active on the li that I've passed. Slick Slider wasn't going to them but now it's working. Here's how I did it:
var current_index = $(".mobile_food_slider .active").attr("data-slick-index");
$(".mobile_food_slider").slick("slickGoTo", current_index);

Hover effect when user touches sliding through nav elements

I've implemented a sidebar navigation with a hover effect to jump from slide to slide on a custom slider which is working fine using a simple jQuery hover() function:
$('#slider-nav ul li').hover(function() {
$(this).prev().addClass('hover-sib');
$(this).next().addClass('hover-sib');
}, function(e) {
$(this).prev().removeClass('hover-sib');
$(this).next().removeClass('hover-sib');
});
but on mobile it would need to be polished.
The idea is to have the same hover effect on real time while the user slides the finger vertically over the lines, making them grow to the side and the text to appear. Once the user releases on an option it could be interesting to call that slide, but that is not the priority right now. The bigger issue is how to achieve the similar effect of a hover when a user slide the finger through the element...
Any idea? I thought on using 'touchmove' but I don't think that I could tell if the user is over one of those options or even which one of them.
$('#slider-nav ul li').bind('touchmove',function(){
$(this).prev().addClass('hover-sib');
$(this).next().addClass('hover-sib');
});
Sample: https://jsfiddle.net/ac_coding/d7xnndg2/
UPDATE: In case it wasn't properly understood/explained, what I'm trying to achieve here is the same hover effect on a desktop when a mobile user touches the screen and, without lifting the finger, moves from along the vertical right edge, hovering and passing through different lines/options of the nav which would be triggering their "hover" effect.
Using touchstart/touchend will require the user to tap at different points of the nav in order to see the options.
I hope it makes sense, doesn't seem easy to explain :S
UPDATE 2: It seems that I finally found a solution but I don't have the time now. I'll update this question tomorrow explaining it for everyone else. Thanks everybody for your help!
Did you try to bind to the touch event? You need to add "hover-effect" class (where :hover styles are) as your additional CSS selector as well.
$('#slider-nav ul li').bind('touchstart', function() {
$(this).addClass('hover-effect');
$(this).prev().addClass('hover-sib');
$(this).next().addClass('hover-sib');
});
$('#slider-nav ul li').bind('touchend', function() {
$(this).removeClass('hover-effect');
$(this).prev().removeClass('hover-sib');
$(this).next().removeClass('hover-sib');
});

javascript keep sub navigation bar open on hover

I created a fiddle
jsfiddle.net/ExaLM/1
Now the sub navigation bar is closing on mouse leave event.
But if I hover on sub link bar then also sub link bar closes.
So what changes should I make in my code for that?
code is
$(document).ready(function(){
$("#main-nav li a.main-link").hover(function(){
$("#main-nav li a.main-link").removeClass("active");
$(this).addClass("active");
$("#sub-link-bar").animate({
height: "40px"
});
$(".sub-links").hide();
$(this).siblings(".sub-links").fadeIn();
});
$("#main-nav li a").mouseleave(function(){
$("#main-nav li a.main-link").removeClass("active");
$(".sub-links").fadeOut();
$("#sub-link-bar").animate({
height: "10px"
});
});
});
I updated your Fiddle
Basically, what you want is to avoid hiding the elements when the mouseleave event is fired. To do so, you could bind on both the a.main-link and its <ul> element, or you can do it like I did: bind your jQuery events on the whole <li> so mouseleave is not triggered until you leave both the main link or the sub-links, as it is contained in the whole <li>. I had to change hover to mouseenter to avoid it being fired repeatedly.
I also had to add some .stop() to avoid the animation repeating entirely every time the mouse gets out of the menu and bounce a few times before finally stopping. You should also remove the .hide() because sometimes when moving the mouse fast, the elements are still visible when they are hidden and it makes it look jerky.
I hope this is enough for you to figure out how to fix your menu.

JQuery hover fadeIn/fadeOut on different divs

I have lists inside a div called header which I want to expand the lists on hover over each list, but I want all the lists which have been hovered over to stay open until the mouse is moved out of the header div. So far I have fadeIn/fadeOut for each list individually or I can get each list to fadeIn and stay open but not fadeOut whenever I move out of the div.
here is the code that I am using: http://jsfiddle.net/jTCdg/11/
The line commented out in the javascript is what changes between all the lists staying visible or the list fadeIn/fadeOut on hover.
This is my first time using javascript so help would be greatly appreciated. thanks
jQuery hover is a shortcut for the mouseenter and mouseleave event handlers. You can define both separately.
$(document).ready(function() {
$("#header ul").mouseenter(function() {
$(this).find("li").fadeIn();
});
$("#header").mouseleave (function() {
$(this).find("li").fadeOut();
});
});
Also see the updated jsfiddle.

animating div elements left to right and back

I have a menu system made up of divs and i want to animate the left property to slide each time the user mouses over a menu item but i need the outer div(which is black) element to expand as the menu items move left to right also I want the div element(.container) to slide back and contract the outer div element(this black div which is 0 width) I have a basic example done in jsFiddle it olny moves the elements to the left
Having a little trouble fully understanding, but is this sort of what you mean?
http://jsfiddle.net/V3RHr/2/
If I could rewrite your html a bit, I would put make each .menu-item into an unordered list.
When you mouseenter the unordered list, you expand the second container. Inside that mouseenter function, I would have a second event when you mouseenter a list item, you populate the second container and stopPropogation.
You could probably still do it with a mouseenter on the first container, and another mouseenter on the div.menu-item, but your first container has extra height and width.
You should be able to fix the left is null issue by having the code not execute on the last .content, like this:
$('.container').not(':last').find('.menu-item').mouseenter(function () {
This will not apply to the menu-items within the green box.
For the re-show issue, I would change the way you are showing. Instead of sliding the box out from behind the other, you can position it where you want it to end up and hide it, then you can use:
.animate({width: 'show'})
Which will give a similar sliding effect.
That, or do it similar to my response to your other question, only without the collapsing I had previously:
http://jsfiddle.net/V3RHr/3/

Categories

Resources