I've made a sub menu list that show/hide with jquery when user hover on li list, each li shows a separate element.
Now i'm facing a problem with the jQuery code that when mouseleave, it hide the element and can't detect the hover event over this element.
The thing is, I can make it hide when switching to another list menu item and getting out of the element block. but I need it to keep showing the submenu in case the mouse is over it.
here's the code:
$(".left-nav-list-view nav ul li").mouseenter(function () {
clearMenuFlyout();
if ($(this).data('has-submenu')) {
var submenu_id = $(this).children('a').data('menu-id');
$(".flyOut-nav-container").append($("[id=" + submenu_id + "]")).position({
my: "left+1 top+0",
at: "right top",
of: this
});
}
}).on("mouseleave", function () {
});
function clearMenuFlyout(){
$(".flyout-temp-container").append($(".flyOut-nav-container").children());
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="side-nav-container flex-fixed">
<nav class="left-nav-view collapsed" role="navigation">
<div class="app-logo">
<div class="burger-menu">
<span class="burger-menu-icon"></span>
</div>
</div>
<div class="left-nav-list-view">
<nav>
<ul>
<li><span>Dashboard</span></li>
<li id="AccountingMenu" data-has-submenu="true"><a data-menu-id="AccountingMenuItems" href="#"><span>Accounting</span><i class="list-in fa fa-chevron-right"></i></a></li>
<li id="InventoryMenu" data-has-submenu="true"><a data-menu-id="InventoryMenuItems" href="#"><span>Inventory</span><i class="list-in fa fa-chevron-right"></i></a></li>
</ul>
</nav>
</div>
</nav>
</div>
basically clearFlyout function takes an already existent menu element and throw it to another div. .flyout-temp-container is hidden by default
Related
I have a menu structure where the Submenu that is hidden is not a child of the menu item. I have a span element inside the main top level link that will serve as an arrow to signify a submenu on mobile. When the user touches the span element I need the dropdown menu to have a class added (Javascript not using jQuery) in order to show it.
Something like this (Note that this is not how I would structure my menu, this is code already on a site that I cannot change)
<a href="#">Top Level Menu Item #1
<span>⇩</span>
</a>
<div class="dropdown-menu">Dropdown Menu Here</div>
<a href="#">Top Level Menu Item #2
<span>⇩</span>
</a>
<div class="dropdown-menu">Dropdown Menu Here</div>
<a href="#">Top Level Menu Item #3
<span>⇩</span>
</a>
<div class="dropdown-menu">Dropdown Menu Here</div>
So when span is touched or clicked, .dropdown-menu will have a class added to it.
Just go with span.parentNode.nextElementSibling.classList.toggle('visible');
const spans = document.querySelectorAll('a>span');
for (const span of spans) {
span.addEventListener('click', (e) => {
e.stopPropagation();
span.parentNode.nextElementSibling.classList.toggle('visible');
})
}
.dropdown-menu {
opacity: 0;
transition: all .2s ease-in-out;
}
.dropdown-menu.visible {
opacity: 1;
}
<a href="#">Top Level Menu Item #1
<span>⇩</span>
</a>
<div class="dropdown-menu">Dropdown Menu Here</div>
<a href="#">Top Level Menu Item #2
<span>⇩</span>
</a>
<div class="dropdown-menu">Dropdown Menu Here</div>
<a href="#">Top Level Menu Item #3
<span>⇩</span>
</a>
<div class="dropdown-menu">Dropdown Menu Here</div>
Please note that I have limited the click listener to the <span>⇩</span> , the link itself is not affected.
Let me know if you need IE11-compatible code.
You can just walk the dom, if that's the structure it will always have HTML wise with something like(providing you add a class to it, a wrapping class/id or something unique to the span):
const spans = Array.from(document.querySelectorAll('.dropdown-toggle'))
const addClassToSubmenu = el => {
el.target.parentNode.nextElementSibling.classList.toggle('classtoadd')
}
spans.forEach(span => {
span.addEventListener('click', addClassToSubmenu)
})
That'd do.
That's the snippet:
https://codepen.io/Venomzzz/pen/qJyvyN?editors=1010
You could try accomplishing this with jQuery next():
Note: you need to add a "menu" class to your tags and you'd need to expand the mouseout and hover calls to keep your sub-menus from going away when you mouse out of the main menu.
CSS:
.dropdown-menu {display: none }
HTML:
<a href="#" class="menu">Top Level Menu Item #1
<span>⇩</span>
</a>
<div class="dropdown-menu">Dropdown Menu Here</div>
<a href="#" class="menu">Top Level Menu Item #2
<span>⇩</span>
</a>
<div class="dropdown-menu">Dropdown Menu Here</div>
<a href="#" class="menu">Top Level Menu Item #3
<span>⇩</span>
</a>
<div class="dropdown-menu">Dropdown Menu Here</div>
JQuery:
$('.menu').hover(function() {
$(this).next().css("display", "block");
});
$('.menu').mouseout(function() {
$(this).next().css("display", "none");
});
I'm trying to get my responsive navigation to collapse when clicking a navigation item (link).
This is my navigation:
<nav class="nav">
<ul>
<li class="nav-item">Overview</li>
<li class="nav-item">Amenities</li>
<li class="nav-item">Residences</li>
<li class="nav-item">Neighborhood</li>
<li class="nav-item">Availability</li>
<li class="nav-item">Contact</li>
<li class="btn login">Login</li>
<li class="nav-toggle"></li>
</ul>
</nav>
Here's how the responsive nav gets expanded:
<script>
function myFunction() {
document.getElementsByClassName("nav")[0].classList.toggle("responsive");
}
</script>
I'm not sure why you're mixing old school list tags with the modern Nav because you don't need them.
If you want the menu to collapse upon selection you can use this neat technique:
<nav style="position:absolute; left:20px; top:50px;">
<div onclick="TheBox.removeAttribute('open');">
<details id="TheBox"><summary>Choices</summary>
Home<br>
About<br>
Products<br>
Services<br>
Contact
</div></details></nav>
It looks like you want to hide the navigation when the toggle link is clicked. If so, I would do the following. Note that your <a> tags were outside the <li> tags, I've moved them inside.
<nav id="nav">
<ul>
<li class="nav-item">Overview</li>
<li class="nav-item">Amenities</li>
<li class="nav-item">Residences</li>
<li class="nav-item">Neighborhood</li>
<li class="nav-item">Availability</li>
<li class="nav-item">Contact</li>
<li class="btn login">Login</li>
<li class="nav0item">Toggle</li>
</ul>
</nav>
I would target by ID and not class, and set the display to none.
<script type="text/javascript">
function collapseNav() {
document.getElementById('nav').style.display = "none";}
</script>
Since your toggle is on a <li> inside the nav, your navigation menu (and the toggle) will be hidden when activated. So, I'd make a way to show it again. You could, for instance, add this function in your JS.
function showNav() {
document.getElementById('nav').style.display = "block";}
And then add a link somewhere for the user to show the menu again.
<button onclick="showNav();" >Show Menu</button>
If you go that route, I'd also hide the Show Menu button by default by adding id="shownav" style="display: none;" to hide it initially. And then have your collapseNav function also show the button:
document.getElementById('shownav').style.display = "block";
Thank you for your responses.
This is what I was looking for:
$(document).ready(function(){
$("li.nav-item a, .logo").click(function(){
$("nav").removeClass("responsive");
});
});
Now the "responsive" class gets removed when clicking on a navigation item or the logo, so my navigation returns to collapsed mode.
I'm writting a dropdown menu and I wanted to have the dropdown being controlled by javascript.
My dropdown has the sub menu hidden of sight max-height: 0px; and when the correspondent anchor tag is clicked, I change its max-height parameter to 400px, using the following function:
function drop_down(name) {
document.getElementById(name).style.maxHeight = "400px";
}
So far so good. The problem is that the element's max-height, stays at 400px and the sub menu does not hide. So I thought that I should target the click of the mouse and when this happens check if there is any element with 400px and change it back to 0.
$('html').click(function() {
var max_h = document.getElementsByClassName("nav_content");
var i;
for(i = 0 ; i < max_h.length ; i++)
{
if(max_h[i].style.maxHeight == "400px")
{
max_h[i].style.maxHeight = "0px";
}
}
});
What happens is that this function tracks every click, even the one used to display the sub menu. So my question is: is there a way to only activate the second function after I clicked my sub-menu? Because I always want the click that comes after the menu is displayed to close the sub menu.
HTML:
<body>
<div class="nav_container">
<nav class="nav_main">
<div class="logo">
<a href="#">
<img src="../majo.png" alt="logo">
</a>
</div>
<ul class="nav" id="nav">
<li>
Home
</li>
<li>
Consultas
<div id="nav_consul" class="nav_content">
<div class="nav_sub">
<ul>
<li>
Informação Dia a Dia
</li>
<li>
Totais Mensais
</li>
<li>
Tarifário Atual da Rede
</li>
<li>
Data específica
</li>
<li>
Atividade do Sistema
</li>
<li>
Coimas
</li>
</ul>
</div>
</div>
</li>
<li>
Simulações
<div id="nav_simul" class="nav_content">
<div class="nav_sub">
<ul>
<li>
Criar tarifa Simples
</li>
<li>
Criar tarifa Complexa
</li>
<li>
Simular com Nova Tarifa
</li>
</ul>
</div>
</div>
</li>
<li>
Preferências
<div id="nav_prefs" class="nav_content">
<div class="nav_sub">
<ul>
<li>
Lista de acessos
</li>
<li>
Alterar Password
</li>
<li>
Alterar Dados de Conta
</li>
</ul>
</div>
</div>
</li>
<li>
Log Out
</li>
</ul>
</nav>
</div>
<div id="content_main">
</div>
<footer></footer>
<script src="../js/jQuery.js"></script>
<script src="../js/user_menu.js"></script>
<script src="../js/user_nav.js"></script>
<script src="../js/user_clear_sub_menu.js"></script>
</body>
Here is an easy solution:
Create the following CSS-Styles:
.nav_content.visible {
max-height: 400px;
}
.nav_content.invisible {
max-height: 0px;
}
Set the overflow property for your nav_content to hidden:
.nav_content{
overflow: hidden;
}
Now add the class invisible to your submenus, if you want them to be invisible by default (you can do this manually in the markup or by js code):
Manually e.g.:
<div id="nav_prefs" class="nav_content invisible">
or by code (after the elements have been loaded):
$(".nav_content").addClass("invisible);
Now, if you just need to adjust your drop_down function to toggle the element's invisible/visible class:
function drop_down(dropdownID){
$('#'+dropdownID).toggleClass("visible invisible");
}
UPDATE: To make all visible submenus disappear when clicked elsewhere use this piece of code, when the window is loaded:
$(document).on('click', function (e) {
if (!$(e.target).is('.nav_item') && !$(".nav_item").has(e.target).length !== 0) {
$('.nav_content.visible').toggleClass("visible invisible");
}
});
If you only want to have one submenu visible at a time, you can use this version of your drop_down function:
function drop_down(dropdownID) {
$('.nav_content.visible').toggleClass("visible invisible");
$('#' + dropdownID).toggleClass("visible invisible");
}
A working fiddle can be found here
EDIT: Since you used jQuery in your original code, I assumed the answer can use jQuery too
You'll want to create a click handler on your document, then check the target of the click. If the target of the click has a certain class, use the menu behavior. If not, or if it's a sub-menu, close the menu.
Here's a question with multiple examples:
How do I close menu on click and when the user clicks away?
Also, I'd recommend not using max-height to hide and show. Since you're using jquery already, you could just use hide() and show().
One more thing: since you're using jquery already, you don't need to use these calls: document.getElementById(name). You can do a $("#yourId") or for document.getElementsByClassName("nav_content"); you can use $(".your-class")
It looks like you attached click event to entire document. I think you need to change only $('html').click(function() { to something like $('sub-menu-selector').click(function() { to
only activate the second function after I clicked my sub-menu
Aside to that, since it's only piece of jQuery and if you're not using it elsewhere, I would replace this with addEventListener and attachEvent, but maybe that's just me :)
In that case you can use jQuery.not() method to exclude the dropdown menu from your jQuery selection, here's what you need :
$('html').not(document.getElementsByClassName("nav_container")[0]).click(function() {
//As you can pass an element to it
You can also use the :not in your first selector like this:
$('html:not(div.nav_container))
i have this html and javascript for my menu button
THIS IS THE HTML
MENU
<div class="mobilenav">
<li>HOME</li>
<li>SERVICES</li>
<li>WORK</li>
<li>TALK</li>
</div>
ICON
<a href="javascript:void(0)" class="icon">
<div class="MENU">
<div class="menui top-menu"></div>
<div class="menui mid-menu"></div>
<div class="menui bottom-menu"></div>
</div>
</a>
AND JS
$(document).ready(function () {
$(".icon").click(function () {
$(".mobilenav").fadeToggle(500);
$(".top-menu").toggleClass("top-animate");
$(".mid-menu").toggleClass("mid-animate");
$(".bottom-menu").toggleClass("bottom-animate");
});
});
i changed the ".icon" for an "a" so the menu closes as soon as i picked any option, now anytime i clicked on the scroll down button, contact and any other tag button the menu opens, is there any way to stop this from happening?
$("a") selects all links on the page.
Instead you only want the select .icon + the links in the .mobilenav, so you need to do $(".icon, .mobilenav a").
Note that JQuery selectors work almost the same as CSS selectors.
$(document).ready(function () {
$(".icon, .mobilenav a").click(function () {
$(".mobilenav").fadeToggle(500);
$(".top-menu").toggleClass("top-animate");
$(".mid-menu").toggleClass("mid-animate");
$(".bottom-menu").toggleClass("bottom-animate");
});
});
I want yo Change a color of nave when user click on other nav button i don't no how can i do this by code here is a image below:
when user click in abut then that color should be change in orange and home page active orange color will be black and about will be orange. i want to do this by JavaScript. here is a code lines below.
<div class="container clearfix">
<nav id="menu" class="navigation"
role="navigation" style="float: left">
Show navigation
<ul id="nav">
<li class="active">Home</li>
<li>About</li>
<li>T-P</li>
<li>M-P</li>
<li>B-M</li>
<li>R-B</li>
<li>L-C</li>
</ul>
</nav>
</div>
i use this JavaScript for change this.
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/
jquery/1.5.2/jquery.min.js"></script>
<script type="text/javascript">
var make_button_active = function()
{
//Get item siblings
var siblings =($(this).siblings());
//Remove active class on all buttons
siblings.each(function (index)
{
$(this).removeClass('active');
} )
//Add the clicked button class
$(this).addClass('active');}
//Attach events to menu
$(document).ready(
function()
{
$(".menu li").click(make_button_active);
} )
</script>
but nothing happen please let me know how can i do this. anyone have any Idea?
Thank You
There are a number of issues here. For one menu is the value of an id so you would need to reference it in jquery with $('#menu"). Below is a working version of your code. I had to remove the href attributes to achieve the desired style change with minimal effort. You now have two choices:
Use this code and swap content dynamically using javascript and css display property
On each page in your site modify the markup, to set the active nav item; with this approach the javascript is not necessary.
<htmL>
<head>
<script type="text/javascript">
var make_button_active = function(){
//Get item siblings
var siblings =($(this).siblings());
//Remove active class on all buttons
siblings.each(function (index){
$(this).removeClass('active');
});
//Add the clicked button class
$(this).addClass('active');
}
//Attach events to menu
$(document).ready(function(){
$("li").click(make_button_active);
});
</script>
<style>
.active{
background-color: red;
}
</style>
</head>
<body>
<div class="container clearfix">
<nav id="menu" class="navigation"
role="navigation" style="float: left">
Show navigation
<ul id="nav">
<li class="active"><a>Home</a></li>
<li><a >About</a></li>
<li><a >T-P</a></li>
<li><a >M-P</a></li>
<li><a >B-M</a></li>
<li><a >R-B</a></li>
<li><a >L-C</a></li>
</ul>
</nav>
</div>
</body>
</html>
Hi more simple way to chafe class in li
string thisURL = this.Page.GetType().Name.ToString();
switch (thisURL)
{
case "home_aspx":
lihome.Attributes.Add("class", "Active");
break;
case "support_aspx":
lisupport.Attributes.Add("class", "Active");
break;
case "logout_aspx":
lilogout.Attributes.Add("class", "Active");
break;
}
need to do this code on load event of page and it will working that vote for this solution=)