A navigation menu I'm working on has a default CSS behavior (for those rare people who have JavaScript disabled). By default, the submenu is not displayed:
.main-navigation ul ul {
display:none;
}
On hover, the submenu is revealed:
.main-navigation ul li:hover > ul {
display:block;
}
For the JavaScript-minded majority, the menu is juiced up with the following jQuery snippet:
jQuery(document).ready(function($) {
/* cancel the default CSS hover behavior */
$('.main-navigation ul li').on('mouseover',function(){
$('.main-navigation ul li:hover > ul').css('display', 'none');
$(this).css('cursor', 'pointer');
});
/* toggle submenu display (if the submenu actually exists) */
$('.main-navigation ul li a').click(function() {
var li = $(this).closest('li');
if(li.has('ul')) li.find('ul').slideToggle(100);
});
});
This toggling works great, except it only works as long as the mouse cursor stays over the parent link. If the submenu is open, and the user happens to move the mouse away from the parent link, the submenu snaps shut.
Question: How do I keep the submenu open on mouse out, if it's been already open?
I tried adding something like this to my jQuery snippet:
$('.main-navigation ul li').on('mouseout',function(){
if ($('.main-navigation ul li ul').css('display') = 'none') {
$('.main-navigation ul li ul').css('display', 'none');
} else if ($('.main-navigation ul li ul').css('display') = 'block') {
$('.main-navigation ul li ul').css('display', 'block');
}
});
Not only it's mediocre coding, but it also actually doesn't work. ;-(
How should I fix this issue?
Thank you in advance for your suggestions!
i'm not sure the click issue yet (looking at it), but you don't need JavaScript to "disable" the CSS. Simply use <noscript> tags, like so:
<noscript>
<style type="text/css">
.exampleclass:hover { display: block; }
</style>
</noscript>
Or you could simply add a no-js class to you main menu element, then remove that class if JS is enabled at the very start of your JavaScript. Then write your "no-js css" to use .no-js + whatever children instead of the main class.
UPDATE
The problem is simple, when you use mouseover to cancel your "non-js" css, the menu is still being hidden everytime the user hovers over that submenu. In other words, you're not just removing the "no js" css, you're hiding it on every mouseover of .main-navigation ul li!
Simply follow something in my first suggestion, then remove the mouseover function completely and viola! problem solved!
I wrote a jsFiddle using your code to show how I might approach it.
jsFiddle
Code
$(function() {
// See in css where i changed `.main-navigation ul li:hover > ul` to `.main-navigation.no-js ul li:hover > ul`
// See Also in HTML where i added class `no-js` to `#site-navigation`
$(".no-js").removeClass("no-js");
$('.main-navigation ul li a').on("click", function(e) {
// first hide sibling sub-menus!
$(this).closest('li').siblings().each(function(i) { $(this).find("ul").slideUp("fast"); });
// no need for the if statement you had.
// jQuery is "smart", if it doesn't exist,
// then this function simply won't do anything!
$(this).closest('li').find('ul').slideToggle(100);
})
// and just to add a little for ya,
// the following will slideUp our submenu if user hovers away from MAIN MENU
.closest("ul").on("mouseleave", function(e) {
$(this).find("ul:visible").slideUp("slow");
});
})
Step-by-Step
Where you have manual script at between <script type="text/javascript"> tags, just before that noscript tage you threw in(which you can remove), replace all your JS with the following:
<script type="text/javascript">
jQuery(document).ready(function(jQuery) {
jQuery(".no-js").removeClass("no-js");
jQuery('.main-navigation ul li a').on("click", function(e) {
$(this).closest('li').siblings().each(function(i) { $(this).find("ul").slideUp("fast"); });
jQuery(this).closest('li').find('ul').slideToggle(100);
})
// If you find the menu hiding to fast, simply remove or comment out the next 3 lines
jQuery('.main-navigation ul').on("mouseleave", function(e) {
jQuery(this).find("ul:visible").slideUp("slow");
});
});
</script>
Remove the NOSCRIPT TAGS
In your CSS Code:
/* Find the area that was written as */
.main-navigation ul li:hover > ul {
display:block;
}
/* And replace it with the following */
.main-navigation.no-js ul li:hover > ul {
display:block;
}
Finally, look in your HTML, find the line written as <nav id="site-navigation" class="main-navigation" role="navigation"> and replace it with:
<nav id="site-navigation" class="main-navigation no-js" role="navigation">
so here is where IE did something neat, and jquery makes it browser agnostic so it's usable. mouseleave is 'mouseout' for the selected element and any of its subelements in IE, and jquery makes it work for the other browsers.
The mouseleave JavaScript event is proprietary to Internet Explorer.
Because of the event's general utility, jQuery simulates this event so
that it can be used regardless of browser. This event is sent to an
element when the mouse pointer leaves the element. Any HTML element
can receive this event.
mouseover - when someone mouses over the 'parent' ul li you want to show any sub uls
click - when someone clicks the parent ul li you want to hide or show any sub uls
mouseleave - IE specific that jquery makes browser agnostic for you.
leave the menus in a working state using <noscript> tags, and intend the javascript to go from there if it is available.
fiddle -- this fiddle is just to give you a start, as i didn't put in any of your css.
$(function () {
$("ul").on({"mouseover":function(event){
$(this).find("ul").show("slow");
}},"li.menu-item",null).on({"click":function(event){
$(this).find("ul").toggle("slow");
}},null,null).on({"mouseleave":function(event){
$(this).find("ul").hide("slow");
}},null,null);
});
Related
When I click a tab on my navbar it will go to the tab, but once I move the mouse away from it will no longer show that it's selected but it will keep it's text color.
Here is the full code:
Html: https://codetidy.com/8744/
CSS: https://codetidy.com/8745/
So that I can better explain my problem here is an example:
Loads the website
Hovers over the about tab to click it
Then after tab has been clicked mouse has moved away but the tab didn't stay red
Try adding a more specific CSS selector to your custom CSS:
.nav > li > a:focus, .nav > li > a:hover {
background-color: red;
}
Working example of your code (after adding the class above)
As what I can see on your html code, why do you have a onClick function for tabs. There is already a documentation for bootstrap tabs. You just need to clear up your css also to get the desired output. You can do something like this as css but it is much better if you put an id for you navbar.
default:
.nav > li {
//enter code here
}
hover:
.nav > li:hover {
//enter code here
}
selected:
.nav > li.active {
//enter code here
}
I have a caret pointing down on my nav item and once the nav item is clicked it displays the dropdown menu and rotates the caret 180 and points it up. Only problem is when you click on another nav item it hides the dropdown but the caret stays pointing up. This is the javascript i'm using
$('.nav li a').click(function() {
$(this).children('.caret').toggleClass("rotate-180");
});
Is there a way to rotate the caret back to pointing down once another nav item has been clicked?
Having not seen your HTML, this is what I came up with:
$('.nav li a').click(function() {
$(this).children('.caret').toggleClass("rotate-180");
$(this).closest('.nav').find('li a').not(this).children('.caret').removeClass("rotate-180");
});
$('.nav li a').click(function() {
if($(this).hasClass('rotate-180')) {
$('.nav li a .caret').removeClass('rotate-180');
} else {
$('.nav li a .caret').removeClass('rotate-180');
$(this).children('.caret').addClass("rotate-180");
}
});
without seeing the code tthis might not be the best solution, but you can add a .removeClass() function prior to the toggleClass to reset all carets to the down position first and then rotate the desired one.
$('.nav li a').click(function() {
$('.nav li a .caret').removeClass("rotate-180");
$(this).children('.caret').addClass("rotate-180");
});
Are you sure you need to toggle classes? Bootstrap is most likely already doing that for you. For example Bootstrap dropdowns will add an open class to the dropdown container div. You can easily create a descendant style for this situation:
.dropdown.open .caret { transform: rotate(180deg); }
I have a script for a responsive menu to toggle the height:
jQuery(function() {
var pull = jQuery('#pull');
menu = jQuery('nav ul');
menuHeight = menu.height();
jQuery(pull).on('click', function(e) {
e.preventDefault();
menu.slideToggle();
});
});
jQuery(window).resize(function(){
var w = jQuery(window).width();
if(w > 320 && menu.is(':hidden')) {
menu.removeAttr('style');
}
});
The problem is that the nested unordered list's height is not taken into account and it just "pops" in and ruins the effect. The HTML markup would be:
<ul>
<li></li>
<li>
<ul>
</ul>
</li>
</ul>
You can see it live at http://www.windycitydigital.net/iconvert. Anyone have any idea how I could prevent that nested UL from ruining the toggle animation and making it all one fluid transition?
A couple things could be useful here:
With the selector you've got there for menu it's going to select both the top level ul as well as any subnav ul...
Try changing that selector to this:
menu = jQuery('nav > ul')
This selector will select only direct child ul's of the nav element, and prevent the slideToggle function from firing on your subnav ul, which looks to include a display block on it in your CSS, styled by the following selector:
#navigation ul ul
Slidetoggle is going to toggle that to display: none with the selector you're currently using.
I'd also strongly consider changing your selectors to be a little cleaner, and more precise:
#navigation > ul
This will select only direct children of the navigation element. Using this selector instead of #navigation ul allows you to use less CSS since you don't have to override styles you've applied for your subnav elements by using the more general #navigation ul selector (which, as you've seen, affects every ul within #navigation).
Since you've applied a class to your sub-nav ul, you can style it directly using:
#navigation .sub-menu
Hopefully this helps steer you in the right direction!
!! Edit (after comment below) !!
Try this JavaScript:
jQuery(function() {
var pull = jQuery('#pull'),
menu = jQuery('.menu', '#navigation');
pull.on('click', function(e) {
e.preventDefault();
menu.slideToggle('medium');
});
});
Oh, and make sure you change the #navigation ul { display: none } to #navigation > ul { display: none }, otherwise the problem mentioned above where the subnav hides will persist...
i am trying to come up with a way of displaying a lot of categories in side list.
The only way i can see as a usable way instead of those annoying fly out menus, is to expand categories upon clicking on parent category.
support have provided a js to display when hover over parent, but want it to expand and close on click, and to close upon another parent is clicked.
<style>
.SideCategoryListClassic ul li ul li {
display: none;
}
</style>
<script type="text/javascript">
$('.SideCategoryListClassic').children().children('li')
.hover(function(){$(this).children('ul').children().slideDown()},
function(){$(this).children('ul').children().slideUp()});
</script>
Hope someone can share some light on this.
Cheers
It's probably best to do this by just adding a class when a parent is clicked.
$('.SideCategoryListClassic li a').click(function(e) {
e.preventDefault(); //This prevents clicking causing the user to actually go to the link they clicked on
$('.SideCategoryListClassic li ul').removeClass('active'); //Removes active class from other submenus
$(this).find('ul').slideDown(); //Adds active class to the submenu of the parent you just clicked on
});
then your css
.SideCategoryListClassic li ul {display:none}
.SideCategoryListClassic li ul.active {display:block;}
Here's a working example: http://jsfiddle.net/Y8Tvu/
I have 2 ULs, each filled with LIs. When I hover over .nav-dayselector ul li a, jQuery is being used to show the corresponding #hover-days ul li in the second UL (this is necessary because the actual code is used inside a carousel with overflow:hidden on , so we need to use 2 separate UL and show them this way.
This works fine - the issue is that when you hover over the span that pops up (#hover-days ul li span), the #hover-days ul li fades out. (see the jsFiddle example)
I need to stop this fadeOut while the mouse is over the span, so that you can use the menu and select items from the :hover span.
Any other way of doing this that works with the 2 separate ULs would be perfectly fine, though. Any simple fix on the jsfiddle that would work?
if you keep a reference to the element you can
tell it to stop fading out when its hovered over
but this requiers the user to reach it with the mousepointer before
its faded out
$(".nav-dayselector ul li a").each(function() {
IndexLI = $(this).parent().index();
var ele = $("#hover-days ul li:eq("+IndexLI+") span");
$(this).hover(function() {
ele.show();
}, function() {
ele.fadeOut();
});
ele.hover(function() {
$(ele).stop().fadeIn();
}, function() {
$(ele).fadeOut();
});
});
the html/css dosent seem to be working in my browser btw (IE 8)