Responsive menu show and hide on click - javascript

I trying to write a responsive menu. It's actually works but I can't get the on clik effect in CSS. For this moment I'm using a hover. How to make that when the screen width is lower than 750px I have to click on menu from pic. number 2 (ul) to show menu from pic. number 3 (li) ? This is a one page site so when I clik on some element from drop down menu it's should hide menu agin (li).
HTML:
<header>
<nav id="menu">
<ul>
<li class="li">WITAJ</li>
<li class="li">O MNIE</li>
<li class="li">DOŚWIADCZENIE</li>
<li class="li">CO ROBIĘ?</li>
<li class="li">KONTAKT</li>
<li>MOJE PRACE</li
></ul>
</nav>
</header>
CSS:
#media screen and (max-width: 750px) {
header nav#menu ul:hover > li{
display:block !important;
}
header nav#menu ul li{
display:none !important;
}
}

You cannot achieve a click effect in CSS. It is common to use JavaScript for that.
This is an easy jQuery solution:
$(function() {
var menuVisible = false;
$('#menuBtn').click(function() {
if (menuVisible) {
$('#myMenu').css({'display':'none'});
menuVisible = false;
return;
}
$('#myMenu').css({'display':'block'});
menuVisible = true;
});
$('#myMenu').click(function() {
$(this).css({'display':'none'});
menuVisible = false;
});
});
It also hides the menu, after the user clicked on an entry.
In CSS, you have to force the menu to be visible or not by using media queries. Here an example: sfplex
This is the HTML structure of this example:
<div id="menuBtn">click me</div>
<nav id="myMenu">
<ul>
<li>entry 1</li>
<li>entry 2</li>
<li>entry 3</li>
<li>entry 4</li>
</ul>
</nav>
See the working example in jsFiddle.

How about something like this:
$('#menu').on('click', function(){
$('#menu ul').css("display", "block");
});
$('#menu a').on('click', function(){
$('#menu ul').css("display", "none");
});

What about using JavaScript for this purpose like this:
$(document).ready(function(){
$("#floor").click(function(){
$("#floor_panel").slideToggle("slow");
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="floor">FLOOR ▾ </div>
<div id="floor_panel">
<form name="floor" action="{{ url_for('select_work', url='Floor') }}" method="post">
{{ floor.name }}
<div id="choose"><input type="submit" value="Choose"></div>
</form>
</div>
</div>
It displays panel floor and by pressing it - panel floor_panel will slide.

Related

Responsively Hiding and Showing Child Elements In Dropdown Menu

I have a dropdown menu that has parent categories that display their children links automatically on Desktop and hide them on mobile until they are clicked. If the window is sized back up the children show again.
This almost works but after resizing the window, if I click the parent category on Desktop it will slideToggle the children elements. It will also run multiple slideToggle events after resizing rather than just one.
I am aware it is likely due to having two instances of slideToggle() but I was having issues when removing one or the other instances. Sometimes they would never open on mobile so I found putting both instances solved this.
I am looking for a less bloated and fully functioning solution. I appreciate all help and I hope to gain knowledge from the answers.
CodePen
//Start Ignore
$('li.dropdown a').on('click', function (event) {
$(this).parent().toggleClass('open');
});
$('body').on('click', function (e) {
if (!$('li.dropdown').is(e.target)
&& $('li.dropdown').has(e.target).length === 0
&& $('.open').has(e.target).length === 0
) {
$('li.dropdown').removeClass('open');
}
});
//End Ignore
/**** CODE I NEED HELP WITH BELOW ****/
$(window).resize(function(){
if ($(window).width()<768){
$('.top-nav-link').on('click', function(event){
event.preventDefault();
$(this).parent().parent().find('.dropdown-nested-links').slideToggle();
console.log('I worked.');
});
}else{
$('.dropdown-nested-links').css('display', 'inline-block');
}
});
if ($(window).width()<768){
$('.top-nav-link').on('click', function(event){
event.preventDefault();
$(this).parent().parent().find('.dropdown-nested-links').slideToggle();
});
}else{
$('.dropdown-nested-links').css('display', 'inline-block');
}
$(window).resize(function(){
if ($(window).width()>768){
//Expands the links when resized back to Desktop
$('.dropdown-nested-links').css('display', 'inline-block');
}else{
//Hides the category dropdown when resized back down to mobile
$('.dropdown-nested-links').css('display','none')
}
});
.dropdown-nested-links{
padding:0;
display:none;
}
#media only screen and (min-width:768px){
.dropdown-nested-links{
padding:0;
display:inline-block;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav class="navbar navbar-inverse">
<ul class="nav navbar-nav learn-nav">
<li class="dropdown">Click Me <span class="glyphicon glyphicon-menu-down"></span>
<ul class="dropdown-menu">
<div class="container-fluid">
<div class="row">
<div class="col-sm-6 dropdown-section">
<li>Parent 1</li>
<ul class="dropdown-nested-links">
<li><span></span>Child</li>
<li><span></span>Child</li>
<li><span></span>Child</li>
</ul>
</div>
<div class="col-sm-6 dropdown-section inverse-section">
<li><a class="top-nav-link" href="#">Parent 2</a></li>
<ul class="dropdown-nested-links">
<li><span></span>Child</li>
<li><span></span>Child</li>
</ul>
</div>
</ul>
</li>
</ul>
</nav>
You should either remove the click event or make the condition inside the click event :
$('.top-nav-link').on('click', function(event){
if ($(window).width()<768){
event.preventDefault();
$(this).parent().parent().find('.dropdown-nested-links').slideToggle();
console.log('I worked.');
}
});
$(window).resize(function(){
if ($(window).width()>=768){
$('.dropdown-nested-links').css('display', 'inline-block');
}
});

how to make this slide menu work

Example: https://jsfiddle.net/lmgonzalves/xj6a74jy/1/
Result: I would like to make a slideUp + slideDown menu the has multiple levels.
I'm stuck trying to get this slide menu to work and I'm not sure how about to get it to work. I've tried using "height"0px" on some css when clicked but ultimately I get back to the same problem. I can make it through the first click in making the slide menu work (meaning there is a slideUp and slideDown), but any level after that the slider just slides up and not down leaving me with no visible menu. Here is what I have:
$('.mobile-nav .navigation a').on('click',function(e){
e.preventDefault();
var t = $(this);
var active = t.closest('li.active');
active.children('ul,a, li.back').not(t.closest('ul')).slideUp();
t.next('ul').slideDown();
});
.mobile-nav .navigation {background:#eee; width:250px; position:relative;}
.mobile-nav .navigation ul {margin:0; padding:0;}
.mobile-nav .navigation a {display:block; line-height:30px;}
.mobile-nav .navigation li ul {display:none;}
<div class="mobile-nav">
<div class="navigation">
<ul>
<li class="active">
All
<ul style="display:block;">
<li>
Topic 1
<ul>
<li class="back">Back</li>
<li>
Some Topic
<ul>
<li class="back">Back</li>
<li>
Some Topic1
((( the menu keeps getting repeated here going deeper, using the format of BackTopic 1Topic 1Topic2 with varying number of li's in each ul.
So the first ul looks like this:
<div class="mobile-nav">
<div class="navigation">
<ul>
<li class="active">
All
</li>
</ul>
/* With 3 more ul's and li's in each
<ul></ul>
<ul></ul>
<ul></ul>
</div>
</div>
When I click on one of the a href tag's, the menu slides to the next level showing the ul, which is the 2nd ul. But when I click on any of the li a's within this ul, I can see the menu start to slide down, but at the same time, the entire ul slides up showing nothing. The ul that was opened now is display:none; even though the next ul is now showing block. I can't figure out how to keep the slides going as they were in the first click.
I can redo classes and such if there is a better way to make this happen.
Fiddled something for you: Fiddle
Hope this is what you need. Just changed the way of selecting the elements.
(function ($) {
"use strict";
$('.mobile-nav')
.on('click', 'a', function (e) {
var $cTarget = $(e.currentTarget),
$dropdown = $cTarget.next('ul'),
$parentUl = $cTarget.closest('ul'),
$activeElem = $parentUl.find('ul.active');
$parentUl.children('li').each(function (key, elem) {
var $elem = $(elem);
if(!$cTarget.parent('li').is($elem)) {
$elem.slideUp();
}
});
$activeElem.toggleClass('active').slideUp();
if (!$dropdown.is($activeElem)) {
$dropdown.toggleClass('active').slideDown();
}
})
.on('click', '.back', function (e) {
var $cTarget = $(e.currentTarget),
$dropdown = $cTarget.closest('ul');
$dropdown.toggleClass('active').slideUp();
$cTarget.parents('li').first().siblings().slideDown();
});})(jQuery);
So these answers are going to be pretty close to each other, but I haven't seen one that meets your "only one item can be open at a time criteria." The JQuery is a little verbose if you want to stick with slipeUp and slideDown but here's an example of the code for handling it for the top-level unordered lists:
$('.toplevel > span').click(function () {
if ($(this).parent().hasClass('activeTop')) {
$('.activeTop').removeClass('activeTop');
$(this).parent().children('ul').slideUp();
return;
}
$('.activeTop').children('ul').slideUp();
$('.activeTop').removeClass('activeTop');
$(this).parent().addClass('activeTop');
$('.activeTop').children('ul').slideDown();
});
I replaced the a tags with spans (and cleaned up the HTML a bit) so I didn't have to deal with my demo fiddle navigating away, but here's a demo implementing the behavior for both top- and second-level menu items.
Check out this fiddle, I would make your structure a little simpler like this https://jsfiddle.net/jk90pxgt/1/ and then your jQuery is only a couple of lines. You can obviously add back buttons if you would like and styling is up to you but this is just a much cleaner way to do the slide menu. Also don't use links and prevent the default, it is just extra code. Just do your click function on the LI
Here is the jQuery
$(".mobile-menu li").click(function(e){
e.stopPropagation();
$(this).children(".sub-menu").slideToggle();
});
New HTML Structure
<ul class="mobile-menu">
<li>First Item
<ul class="sub-menu">
<li>First Sub-Item
<ul class="sub-menu">
<li>First Sub-Item</li>
<li>Second Sub-Item</li>
</ul>
</li>
<li>Second Sub-Item</li>
</ul>
</li>
<li>Second Item
<ul class="sub-menu">
<li>First Sub-Item
<ul class="sub-menu">
<li>First Sub-Item
<ul class="sub-menu">
<li>First Sub-Item</li>
<li>Second Sub-Item</li>
</ul>
</li>
<li>Second Sub-Item</li>
</ul>
</li>
<li>Second Sub-Item</li>
</ul>
</li>
<li>Third Item</li>
</ul>
And CSS
.sub-menu {
display:none;
}
li {
cursor:pointer;
}
Here is how I was able to make this work:
$('.mobile-nav .navigation a').on('click',function(e){
var t = $(this), li = t.closest('li'), ul = li.closest('ul'), a = ul.siblings('a');
if(li.hasClass('back')) {
e.preventDefault();
//do back code here
var sib = ul.closest('li').siblings('li');
a = ul.parents('ul').eq(0).siblings('a');
ul.slideUp();
sib.add(a).slideDown();
} else if(t.siblings().length > 0) {
e.preventDefault();
li.siblings('li').add(a).slideUp();
t.next('ul').slideDown();
}
});

Dropdown Menu Open width Jquery

I have a problem with a drop down menu that must remain open to the click.
After the menu is open, you can click the link inside and the menu item just clicked.
How can I do to remedy the preventDefault ?
Menu HTML:
<nav class="main-menu">
<ul id="" class="menu">
<li>
Menu One
<div class="sub-menu">
<ul>
<li>test test test</li>
... More links ...
</ul>
</div>
</li>
... More items ...
</ul>
</nav>
This is a portion of code
$('.main-menu li a').click(function(event) {
event.preventDefault();
$('.main-menu').find('.sub-menu').removeClass('open');
$(this).parent().find('.sub-menu').addClass('open');
});
An example is visible here JSFIDDLE
Just remove
$('.main-menu').find('.sub-menu').removeClass('open');
Here is a fiddle you can check out
Get rid of event.preventDefault();
Instead do like this
<a href="#" onclick="return false">
Then give each main menu a class name. And call the click event on that class.
https://jsfiddle.net/btevfik/9m9rufqx/3/
You can replace your selector with a more targeted (.menu > li > a) :
$('.menu > li > a').click(function(event) {
event.preventDefault();
$('.sub-menu.open').removeClass('open');
$(this).parent().find('.sub-menu').addClass('open');
});
JSFiddle

jQuery sliding menu function

hi i have a unordered list menu, trying to make the sub-items slide down and up on clicking at the main items, i wrote a jQuery code that works but when click at open menu it close it and open again, but i was hoping it will just close it.
html
<div class="menuNav">
<ul>
<li><span>item_1</span>
<ul>
<li>sub-item_1-1</li>
<li>sub-item_1-2</li>
<li>sub-item_1-3</li>
<li>sub-item_1-4</li>
</ul>
</li>
<li><span>item_2</span>
<ul>
<li>sub-item_2-1</li>
<li>sub-item_2-2</li>
<li>sub-item_2-3</li>
<li>sub-item_2-4</li>
</ul>
</li>
<li><span>item_3</span>
<ul>
<li>sub-item_3-1</li>
<li>sub-item_3-2</li>
<li>sub-item_3-3</li>
<li>sub-item_3-4</li>
</ul>
</li>
</ul>
</div>
jQuery
$(document).ready(function() {
$('.menuNav ul li').click(function(){
$(this).parent().find('ul').slideUp("fast");
$(this).parent().find("li").removeClass('menuactive');
$(this).find('ul').slideDown("slow");
$(this).addClass('menuactive');
});
$('.menuNav ul .menuactive').click(function(){
$(this).parent().find('ul').slideUp("fast");
});
});
If the li has a class menuactive, call the slideUp() function and remove the class menuactive else call the slideUp() function on all uls, remove the class menuactive from all lis, call slideDown() on the one that was clicked and add the class menuactive to the one that was clicked.
$(document).ready(function() {
$('ul > li > ul').hide();
$('.menuNav > ul > li').click(function() {
if ($(this).hasClass('menuactive')) {
$(this).find('ul').slideUp('fast');
$(this).removeClass('menuactive');
} else {
$(this).siblings().find('ul').slideUp('fast');
$(this).siblings().removeClass('menuactive');
$(this).find('ul').slideDown('fast');
$(this).addClass('menuactive');
}
});
});
.menuactive {
color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="menuNav">
<ul>
<li><span>item_1</span>
<ul>
<li>sub-item_1-1</li>
<li>sub-item_1-2</li>
<li>sub-item_1-3</li>
<li>sub-item_1-4</li>
</ul>
</li>
<li><span>item_2</span>
<ul>
<li>sub-item_2-1</li>
<li>sub-item_2-2</li>
<li>sub-item_2-3</li>
<li>sub-item_2-4</li>
</ul>
</li>
<li><span>item_3</span>
<ul>
<li>sub-item_3-1</li>
<li>sub-item_3-2</li>
<li>sub-item_3-3</li>
<li>sub-item_3-4</li>
</ul>
</li>
</ul>
</div>

How to properly hide a sliding menu?

I have the following menu:
<div id="menuItem">Item1</div>
<div id="subMenu">
<ul>
<li>subitem1</li>
<li>subitem2</li>
<li>subitem3</li>
</ul>
</div>
​
Animated like this:
$('#menuItem').mouseenter(function() {
$('#subMenu').slideDown(400);
}).mouseleave(function() {
$('#subMenu').hide(400);
});
​
Unfortunately, as the mouse leave the submenu, the submenu dissapears. How do I make the submenu only disapears when the mouse leave the menuitem OR the submenu list ? I would like to be able to hover the mouse on the submenu. Notice that there is a gap bewteen the two menus.
jsFiddle here
make the sub-menu actually "inside" the menu-item you are attaching the event to, this way the in/out event only happen when the user actually leaves the menu area
like this:
css
#menuItem {
cursor: pointer;
width: 100px;
}
#menuItem .title {
background-color: orange;
}
#subMenu {
background-color: grey;
margin-top: 5px;
cursor: pointer;
display:none;
width: 80px;
}​
html
<div id="menuItem">
<div class="title">Item1</div>
<div id="subMenu">
<ul>
<li>subitem1</li>
<li>subitem2</li>
<li>subitem3</li>
</ul>
</div>
</div>​​​​​​​​​
js
$('#menuItem').mouseenter(function() {
$('#subMenu').slideDown(400);
}).mouseleave(function() {
$('#subMenu').hide(400);
});
friendly note:
you might want to use some form of .stop(true, true) prior to animating the menu, or else moving a cursor back and forth rapidly over the menu will cause the animations to "stack" and it will just feel strange to the user. see discussion here: Where to put clearQueue in jQuery code
so it would look like this:
$('#menuItem').hover(function() {
$('#subMenu').stop(true, true).slideDown(200);
}, function() {
$('#subMenu').stop(true, true).slideUp(200);
});
Try this:
<div id="menuItem">Item1
<div id="subMenu">
<ul>
<li>subitem1</li>
<li>subitem2</li>
<li>subitem3</li>
</ul>
</div>
</div>
This works in my browser (firefox)
Assuming you wanted to keep the exact same html structure, you could use the following code:
$('#menuItem').mouseenter(function() {
$('#subMenu').slideDown(400);
}).next('#subMenu').mouseleave(function() {
$('#subMenu').hide(400);
});
Notice that I've told jQuery to hide the #subMenu only when the mouse has left the #subMenu.
It is always good to have the Menu and Sub Menu inside the same container so you don't need to have a separate mouse handler when navigating sub menu.
DEMO
HTML:
<div id="subMenu">
<div id="menuItem">Item1</div>
<ul>
<li>subitem1</li>
<li>subitem2</li>
<li>subitem3</li>
</ul>
</div>
JS:
$('#subMenu').mouseenter(function() {
$('#subMenu ul').slideDown(400);
isInsideSubMenu = true;
}).mouseleave(function() {
$('#subMenu ul').hide(400);
});
CSS:
#subMenu ul { display:none;}
Alternatively if you don't want to have the submenu inside menuitem (which could mess with your CSS, you can wrap everything in a parent div like:
HTML:
<div id="all">
<div id="menuItem">Item1</div>
<div id="subMenu">
<ul>
<li>subitem1</li>
<li>subitem2</li>
<li>subitem3</li>
</ul>
</div>
​</div>​
jQuery:
$('#all').mouseenter(function() {
$('#subMenu').slideDown(400);
}).mouseleave(function() {
$('#subMenu').hide(400);
});
​

Categories