Dropdown doesn't open after closing - javascript

I made a dropdown menu with css but it doesn't close when you click on it. So I added this function to it:
$(".map-button li ul li").on("click", function(){
$(this).parent().hide();
});
It closes when I click on it but it doesn't open anymore when I hover.
This is what I use to open it when I hover on it with CSS:
.map-button li:hover ul{
display: block;
opacity: 1;
visibility: visible;
}
Menu structure:
<ul class="map-button">
<li>Choose item
<ul style="display: none;">
<li data-id="1">Item 1</li>
<li data-id="2">Item 2</li>
</ul>
</li>
</ul>

You need to add another handler:
$(".map-button li").mouseenter(function(){
$(".map-button li ul").show();
});
$(".map-button li").mouseleave(function(){
$(".map-button li ul").hide();
});

jQuery hide() sets display: none, but you need to set visibility: hidden:
$(this).parent().css({ visibility: 'hidden' });

Consider to use all JS implementation (like #Beri suggest to you), but if you want to use CSS :hover to show list:
Add rule in CSS:
.map-button > li ul{
display:none;
}
.map-button > li:hover ul{
display: block;
}
and remove style="display:block" in HTML
<ul class="map-button">
<li>Choose item
<ul>
<li data-id="1">Item 1</li>
<li data-id="2">Item 2</li>
</ul>
</li>
</ul>
JS is ok.
Test it

Related

How add display: block when anchor tag class is active with jquery or javascript?

In my case I have menu like this:
<li class="">
Accounts</i>
<ul style="display: none;">
<li class="">Profile</li>
<li class="">Edit </li>
</ul>
</li>
How to add style display block if anchor tag is active?
First of all remove the "i" element closing tag from your "Accounts" link. After that You should not use inline styling when you are changing display value, instead use separate css file. I would move the display : none from inline to separate css file using selector.
ul {
display: none;
}
// use this if you want to hover
a:hover + ul {
display: block;
}
// use this if you want to click
a:focus + ul {
display: block;
}
It is fairly simple to modify the display property of the parent element based upon some property of a child element using Javascript but in this case I'm not sure how the hyperlink will be assigned the active class when it resides within a hidden element (ul)...
const getparent=(n,e)=>{//utility to find ancestor node of particular type
while( n!=document.querySelector(e) )n=n.parentNode;
return n;
}
// find all nodes that match the `active` class criteria and navigate up the DOM
// until the UL element is found - change it's display property
document.querySelectorAll('li a.active').forEach( a => getparent(a,'ul').style.display='block' )
<li class="">
<i>Accounts</i>
<ul style="display: none;">
<li class="">Profile</li>
<li class="">Edit </li>
</ul>
</li>
For Menu Try this will helpfull
.menu ul{
position: absolute;
display: none;
}
.menu >li{
display: inline-block;
vertical-align: top;
position: relative;
}
.menu li a{
display: block;
padding: 0px 10px;
}
.menu li:hover ul{
display: block;
}
<ul class="menu">
<li>Menu 1</li>
<li>Menu 2
<ul>
<li>Drop Down1</li>
<li>Drop Down2</li>
<li>Drop Down3</li>
</ul>
</li>
<li>Menu 3
<ul>
<li>Drop Down1</li>
<li>Drop Down2</li>
<li>Drop Down3</li>
</ul>
</li>
</ul>

Change vertical slider to horizontal

I am new to jquery and have a vertical menu to be worked upon.The submenus of the menu are too much in number so the menu gets too deep when opened; so I need to slide out the submenus left instead of down when clicked upon.
the jquery code for the vertical menu is as follows:
jQuery(document).ready(function(){
$(".goo-collapsible > li > a").on("click", function(e){
if(!$(this).hasClass("active")) {
// hide any open menus and remove all other classes
$(".goo-collapsible li ul").slideUp(350);
$(".goo-collapsible li a").removeClass("active");
// open our new menu and add the open class
$(this).next("ul").slideDown(350);
$(this).addClass("active");
}else if($(this).hasClass("active")) {
$(this).removeClass("active");
$(this).next("ul").slideUp(350);
}
});
});
I want to replace the slideUp() and slideDown() function with some other alternative without editting the other part of the code.
I would be too grateful to the supporters :)
You can refer below code. Tried to set correct CSS but still it have some bugs but functionality is there what you are looking for.
$(".goo-collapsible > li > a").on("click", function(e){
if(!$(this).hasClass("active")) {
// hide any open menus and remove all other classes
//$(".goo-collapsible li ul").slideUp(350);
$(".goo-collapsible li ul").hide();
$(".goo-collapsible li a").removeClass("active");
// open our new menu and add the open class
//$(this).next("ul").slideDown(350);
$(this).next("ul").show().animate({"left":"140px"}, "slow");
$(this).addClass("active");
}else if($(this).hasClass("active")) {
$(this).removeClass("active");
//$(this).next("ul").slideUp(350);
$(this).next("ul").animate({"left":"0px"}, "slow",function(){$(this).hide();});
}
});
.goo-collapsible{
width:120px;
border: solid 1px black;
}
.goo-collapsible > li {
background:cyan;
z-index:10;
opacity:1;
}
.goo-collapsible > li > a {
padding: 6px 9.5px;
}
ul, ol, li {
list-style: outside none none;
margin: 0;
padding: 0;
}
.dropdown-menu{
display:none;
left:0px;
position: absolute;
z-index:5;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<ul class="goo-collapsible">
<li>Main Category
<ul class="dropdown-menu">
<li>Sub Cat 1</li>
<li>Sub Cat 2</li>
<li>Sub Cat 3</li>
</ul>
</li>
<li>
About us
<ul class="dropdown-menu">
<li>History</li>
<li>The team</li>
<li>Our address</li>
</ul>
</li>
</ul>

How to Make a Menu Like Stack Overflow's

I really like the way Stack Overflow has done their dropdown menus on the top. Notice how you must click in order for the dropdown to trigger, but you still must hover to get the dropdown. There is also what seems to be groups - once you click, hover will activate the menus shown in the picture. It is hard to explain, but if you play around for a minute you'll see what I mean. Also, it is important that the last hovered menu will show until a user clicks off again.
Here is what I have so far; note that I almost have the same functionality, except for the last menu hovered doesn't stay dropped (it closes on mouseout when it shouldn't until off-click) and the toggle functionality is sketchy:
$(document).ready(function() {
var depressed = false;
$('.menu').click(function() {
depressed = true;
$('.menu').toggleClass('active');
});
$('.menu').hover(function() {
if (depressed) {
$('.menu').toggleClass('active');
}
});
});
ul {
margin: 0;
padding: 0;
}
ul li {
display: inline-block;
padding: 10px 20px;
background: #333;
color: #eee;
}
ul li.active:hover ul {
display: block;
}
ul li ul {
display: none;
position: absolute;
border: 2px solid #555;
}
ul li ul li {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="menu">button 1
<ul>
<li>sub button 1</li>
<li>sub button 2</li>
</ul>
</li>
<li class="menu">button 2
<ul>
<li>sub button 1</li>
<li>sub button 2</li>
</ul>
</li>
<li class="menu">button 3
<ul>
<li>sub button 1</li>
<li>sub button 2</li>
</ul>
</li>
</ul>
My JS is not cuttin git.
So, what is the best way to go about this?
I haven't peeked into the SO menu, so I don't know how they did it. But this seems to work nicely.
A click on one of the buttons opens the dropdown.
The dropdown is not closed by a 'mouseout', like in your code, but only when another menu is hovered. If you hover outside of the menu area, the lastly hovered menu remains open.
Clicking anywhere closes the menu.
So showing the menu is not directly done by using a :hover pseudo element in CSS, but by adding a class, which remains there even when the menu is unhovered. I think the net result behaves pretty close to Stack Overflow's.
$(function(){
// The event to handle clicks outside of the menu. This will close the menu.
var offEvent =
function(event){
$('.menu-bar').removeClass('active');
$(document).off('click', offEvent);
};
// The click event on the menu buttons, to toggle 'menu mode' as it were.
$(document).on('click', '.menu-bar .menu',
function(event){
event.preventDefault();
$('.menu-bar').addClass('active');
$(this).addClass('active');
// Leave menu mode by clicking anywhere of the menu.
$(document).on('click',
offEvent
);
});
// Hover toggles between the dropdowns of the separate menus.
$('.menu-bar .menu').hover(
function(event){
var $current = $(this);
$('.menu').each(
function(index, element){
var $element = $(this);
if ($element.get(0) == $current.get(0)) {
$element.addClass('active');
} else {
$element.removeClass('active');
}
});
});
});
ul {
margin: 0;
padding: 0;
}
ul li {
display: inline-block;
padding: 10px 20px;
background: #333;
color: #eee;
}
ul li ul {
display: none;
position: absolute;
border: 2px solid #555;
}
ul li ul li {
display: block;
}
.menu .dropdown {
display: none;
}
.menu-bar.active .menu.active .dropdown {
display: block;
}
.menu {
display: inline-block;
position: relative;
border: 1px solid grey;
}
.menu .dropdown {
position: absolute;
top: 100%;
left: 0;
border: 2px solid #555;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="menu-bar">
<li class="menu">button 1
<ul class="dropdown">
<li>sub button 1</li>
<li>sub button 2</li>
</ul>
</li>
<li class="menu">button 2
<ul class="dropdown">
<li>sub button 1</li>
<li>sub button 2</li>
</ul>
</li>
<li class="menu">button 3
<ul class="dropdown">
<li>sub button 1</li>
<li>sub button 2</li>
</ul>
</li>
</ul>
$(document).ready(function() {
$('#M1').click(function() {
$('#M1').toggleClass('active');
$('#M2').removeClass('active');
$('#M3').removeClass('active');
});
$('#M2').click(function() {
$('#M2').toggleClass('active');
$('#M1').removeClass('active');
$('#M3').removeClass('active');
});
$('#M3').click(function() {
$('#M3').toggleClass('active');
$('#M1').removeClass('active');
$('#M2').removeClass('active');
});
});
ul {
margin: 0;
padding: 0;
}
ul li {
display: inline-block;
padding: 10px 20px;
background: #333;
color: #eee;
}
ul li.active ul {
display: block;
}
ul li ul {
display: none;
position: absolute;
border: 2px solid #555;
}
ul li ul li {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="menu" id='M1'>button 1
<ul>
<li>sub button 1</li>
<li>sub button 2</li>
</ul>
</li>
<li class="menu" id='M2'>button 2
<ul>
<li>sub button 1</li>
<li>sub button 2</li>
</ul>
</li>
<li class="menu" id='M3'>button 3
<ul>
<li>sub button 1</li>
<li>sub button 2</li>
</ul>
</li>
</ul>
This works for me.
I've just removed :hover from the end of the .active class and made an individual function for each button.

how to stop dropdown menu child sliding up when clicked

I am attempting to make a dropdown menu that when clicked stays down but also, when clicking anywhere within the dropdown area, it will not slide up. Only when clicked elsewhere on the page should it disappear.
I am struggling to make this happen though. You can see what I am doing here:
HTML
<nav id="moo">
<ul>
<li>Item 1 <i>o</i>
<div class="dropdown">
<ul>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</div>
</li>
<li>Item 1 <i>o</i>
<div class="dropdown">
<ul>
<li>Item 7</li>
<li>Item 8</li>
<li>Item 9</li>
</ul>
</div>
</li>
</ul>
</nav>
CSS
ul { padding: 0px; margin: 0px; }
li { display: inline; }
nav li { position: relative; }
nav i { cursor: pointer; font-weight: bold; background-color: red;padding: 5px; }
.dropdown { display: none; position: absolute; border:1px solid #ccc; padding: 10px; }
.dropdown li {
display: block;
}
SCRIPT
$('nav li').click(function () {
var $childDropdown = $(this).find('.dropdown');
if ($childDropdown.is(':visible')) {
$('.dropdown').slideUp(300);
} else {
$('.dropdown').slideUp(300);
$childDropdown.slideDown(300);
}
});
/* Anything that gets to the document
will hide the dropdown */
$(document).click(function(){
$(".dropdown").hide();
});
/* Clicks within the dropdown won't make
it past the dropdown itself */
$("nav").click(function(e){
e.stopPropagation();
});
Here is fiddle version:
http://jsfiddle.net/susannalarsen/buNq9/
You will need to work with the event target property and traverse up its parents to find out what element has triggered the event. if it's an element inside ".dropdown" class, then no sliding-up should be applied, otherwise close dropdown.
example
$('nav > ul > li').click(function (e) {
var $childDropdown = $(this).find('.dropdown');
if ($childDropdown.is(':visible')) {
var target = $(e.target);
if (!$(target).parents(".dropdown").length) {
$('.dropdown').slideUp(300);
}
} ...
Notice that i changed the selection in $('nav > ul > li'), which will apply only to the LI elements of the upper level.

jquery - using stoppropagation for multiple events

I am using stopPropegation to aid me in the way my dropdowns work.
I am using it for multiple dropdowns to help me keep the dropdown open but if the user clicks anywhere else on the page then it will slide up the menu.
HTML
<nav id="moo">
<ul>
<li>Item 1 <i>o</i>
<div class="dropdown">
<ul>
<li>Item 2</li>
<li>Item 3</li>
<li>Item 4</li>
</ul>
</div>
</li>
<li>Item 1 <i>o</i>
<div class="dropdown">
<ul>
<li>Item 7</li>
<li>Item 8</li>
<li>Item 9</li>
</ul>
</div>
</li>
</ul>
</nav>
<div class="clear"></div>
<div id="login-top">Login</div>
<div id="user">roooar</div>
CSS
ul { padding: 0px; margin: 0px; }
li { display: inline; }
nav li { position: relative; }
nav i { cursor: pointer; font-weight: bold; background-color: red;padding: 5px; }
.dropdown { display: none; position: absolute; border:1px solid #ccc; padding: 10px; }
.dropdown li {
display: block;
}
.clear {
clear:both;
}
#login-top {
background:blue;
padding:10px;
color:white;
margin-top:30px
}
#user {
background:pink;
margin-top:10px;
padding:50px;
}
SCRIPT
$('#login-top').click(function () {
var $user = $('#user');
if ($('#user').is(':visible')) {
$user.slideUp(300);
} else {
$user.slideUp(300);
$user.slideDown(300);
}
});
$('nav > ul > li').click(function (e) {
var $childDropdown = $(this).find('.dropdown');
if ($childDropdown.is(':visible')) {
var target = $(e.target);
if (!$(target).parents(".dropdown").length) {
$('.dropdown').slideUp(300);
}
} else {
$('.dropdown').slideUp(300);
$childDropdown.slideDown(300);
}
});
/* Anything that gets to the document
will hide the dropdown */
$(document).click(function () {
$(".dropdown").hide();
$("#user").slideUp();
});
/* Clicks within the dropdown won't make
it past the dropdown itself */
$("nav, #login-top, #user").click(function (e) {
e.stopPropagation();
});
I have 2 questions really about this.
Say if I click open the dropdown menu because I have included certain elements to be exempt from clicking elsewhere on the page - If I click anywhere else it will slide back up exactly how I want.
However, if I happen to click on the #login-top this will not make it slide up as I have added it to the code for the stopPropagation
Is there a may of making it work so that when ".dropdown" is active then you can click absolutely everywhere (including on the <div id='login'> And then when "#login" and "#user" is active you can click anywhere on "nav" and it will still slide up the div?
Is it the right thing to be doing by grouping all the classes and id's into the code:
$("nav, #login-top, #user").click(function (e) {
e.stopPropagation();
});
(I am struggling to explain this but hopefully you can see what I mean if you look at the fiddle version)
http://jsfiddle.net/susannalarsen/Nt2ZM/1/

Categories

Resources