jQuery hide bootstrap slide menu when clicked anywhere on the screen - javascript

Made a Fiddle here:
https://jsfiddle.net/r94dq2e4/
I am using twitter bootstap version 3 with a slide in menu from the left when navbar toggle button is clicked.
This is the jQuery code I'm using:
// Nav
(function ($) {
'use strict';
// Toggle classes in body for syncing sliding animation with other elements
$('#bs-example-navbar-collapse-2')
.on('show.bs.collapse', function (e) {
$('body').addClass('menu-slider');
})
.on('shown.bs.collapse', function (e) {
$('body').addClass('in');
})
.on('hide.bs.collapse', function (e) {
$('body').removeClass('menu-slider');
})
.on('hidden.bs.collapse', function (e) {
$('body').removeClass('in');
});
})(jQuery);
This works well and on first click of the navbar toggle button, the menu slides in, when clicked again, the menu slides out. I would like to enhance this functionality in such a way that the menu slides out when the user clicks anywhere on the page except for the menu itself.
This is my HTML for the menu:
Toggle navigation
Menu
<div class="navbar-collapse collapse" id="bs-example-navbar-collapse-2">
<ul class="nav navbar-nav">
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#">Treatments<b class="caret"></b></a>
<ul class="dropdown-menu">
<li>Menu Item</span></li>
</ul>
</li>
<li>About Us</li>
<li>Meet the team</li>
<li>See the results</li>
<li>Cost</li>
<li>Information</li>
</ul><!-- end navbar-nav -->
</div><!-- end navbar-collapse -->
</nav><!-- end navbar -->
I have started with the following jQuery code to achieve this. But I would need some help in where to go from here:
/* Nav click outside hide navbar */
$(document).click(function(e){
// Check if click was triggered on or within #menu_content
if( $(e.target).closest("#navbar2").length > 0 ) {
return false;
}
// Otherwise
// trigger your click function
$('body').removeClass('menu-slider');
$('body').removeClass('in');
});
Thank you

There are 3 things that you need to check in order to see if you should close the menu:
The element is not the nav itself (.nav)
The element is not the nav container (.navbar-cllapse)
The element is not a child-element of the nav (.parents('.nav'))
if (!$(e.target).hasClass('navbar-collapse') && !$(e.target).hasClass('nav') && $(e.target).parents('.nav').length == 0) {
$('#bs-example-navbar-collapse-2').removeClass('in');
}
You can try it in this fiddle:
https://jsfiddle.net/r94dq2e4/1/

Related

Can't target two different dropdowns properly by jQuery

I have two seperate dropdowns, whose hover states can't be target by css based on the html markup. I tried to solve this by jQuery and I am halfway done. One problem still exists all the time and I am trying to solve this by days now.
If I hover the link of the second dropdown and moves the mouse really fast to the link of the first dropdown and then move the mouse immediately into the container of the displayed first dropdown, this dropdown menu disappears. It seems that my script removes the adding css classes in this case. This situation only appears with fast mouse movement but it drives me crazy. I am unable to figure out why this happens. I include a jsfiddle demo, where you can see the problem by yourself.
jQuery
jQuery(document).ready(function($) {
var $body = $('body'),
$tg_header = $('#main-header'),
$tg_top_menu = $('ul.nav'),
/*$tg_submenu_link = $('.tg-submenu__link'),*/
$tg_submenu_link_tg = $('.tg-submenu__link--tg'),
$tg_submenu_link_abteilungen = $('.tg-submenu__link--abteilungen'),
$tg_submenu = $('.tg-submenu'),
$tg_submenu_tg = $('.tg-submenu__tg'),
$tg_submenu_abteilungen = $('.tg-submenu__abteilungen'),
et_menu_hover_triggered = false;
/* General Hiding Function for first mega menu */
function tg_hide_tg() {
setTimeout( function () {
if ($tg_top_menu.find('.tg-submenu__link--tg:hover').length == 0 && $('.tg-submenu__tg:hover').length == 0) {
$body.removeClass('tg-submenu__tg--active')
};
}, 50);
}
/* General Hiding Function for second mega menu */
function tg_hide_abteilungen() {
setTimeout( function () {
if ($tg_top_menu.find('.tg-submenu__link--abteilungen:hover').length == 0 && $('.tg-submenu__abteilungen:hover').length == 0) {
$body.removeClass('tg-submenu__abteilungen--active')
};
}, 50);
}
/* Mouse Hover Mega Link 1 and Leave Link */
$tg_submenu_link_tg.mouseenter(function() {
$body.addClass('tg-submenu__tg--active');
}).mouseleave(function() {
tg_hide_tg();
});
/* Mouse Leave Mega Menu Container 1 */
$tg_submenu_tg.mouseleave(function () {
setTimeout(function () {
if ($('.tg-submenu__link--tg:hover').length == 0 && $('.tg-submenu__tg:hover').length == 0 ) {
$body.removeClass('tg-submenu__tg--active');
};
},50)
});
/* Mouse Hover Mega Link 2 and Leave Link */
$tg_submenu_link_abteilungen.mouseenter(function() {
$body.addClass('tg-submenu__abteilungen--active');
}).mouseleave(function() {
tg_hide_abteilungen();
})
/* Mouse Leave Mega Menu Container 2 */
$tg_submenu_abteilungen.mouseleave(function () {
setTimeout(function () {
if ($('.tg-submenu__link--abteilungen:hover').length == 0 && $('.tg-submenu__abteilungen:hover').length == 0 ) {
$body.removeClass('tg-submenu__abteilungen--active');
};
},50)
});
});
HTML-Markup
<body>
<header id="main-header">
<div class="container">
<div id="et-top-navigation">
<div class="tg-mainMenu__left">
<nav id="top-menu-nav">
<ul id="top-menu" class="nav">
<li id="menu-item-154" class="tg-submenu__link tg-submenu__link--tg menu-item">MEGA LINK 1</li>
<li id="menu-item-156" class="tg-submenu__link tg-submenu__link--abteilungen menu-item">MEGA LINK 2</li>
<li id="menu-item-166" class="menu-item menu-item">Normal Link 3</li>
</ul>
</nav>
</div><!-- TG-mainMenu__left-->
<div class="tg-mainMenu__right">
<nav id="top-menu-nav">
<ul id="top-menu" class="nav">
<li id="menu-item-154" class="menu-item menu-item">Normal Link 4</li>
<li id="menu-item-154" class="menu-item menu-item">Normal Link 5</li>
<li id="menu-item-154" class="menu-item menu-item">Normal Link 6</li>
</ul>
</nav>
</div> <!-- tg-mainMenu__right -->
</div> <!-- #et-top-navigation -->
<!-- TG Mega 1 -->
<div class="tg-submenu tg-submenu__tg">
<div class="container tg-submenu__content">
<h1>
MEGA MENU 1
</h1>
</div>
</div>
<!-- Abteilungen Mega -->
<div class="tg-submenu tg-submenu__abteilungen">
<div class="container tg-submenu__content">
<h1>
MEGA MENU 2
</h1>
</div>
</div>
</div> <!-- .container -->
</header>
</body>
My fiddle: https://jsfiddle.net/hfammzce/
I dont know why this is happening. But you can use jQuery .show() and .hide() instead of using add/remove class and opacity.
Here is the updated fiddle: https://jsfiddle.net/1dzyszdq/
/* General Hiding Function for first mega menu */
function tg_hide_tg() {
setTimeout( function () {
if ($tg_top_menu.find('.tg-submenu__link--tg:hover').length == 0 && $('.tg-submenu__tg:hover').length == 0) {
$(".tg-submenu__tg").hide();
};
}, 50);
}
/* Mouse Hover Mega Link 1 and Leave Link */
$tg_submenu_link_tg.mouseenter(function() {
$('.tg-submenu__tg').show();
}).mouseleave(function() {
tg_hide_tg();
});

Collapse responsive nav when clicking link

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.

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

Prevent closing sub menu on page changing

I write this function for open and close sub menu and it works fine but I have this problem:
If user click a submenu item and open the page(this menu is in master page) the submenu doesnt close. How can I do that??
fiddler Link (more clear with css)
$(document).ready(function () {
$('.has-sub > a').click(function (e) {
e.preventDefault();
var submenu = $(this).next();
if (submenu.is(":visible")) {
submenu.slideUp();
$(this).closest("li").removeClass("active");
}
else {
submenu.slideDown();
$(this).closest("li").addClass("active");
}
});
});
///my html menu it is in my masterpage(i use mvc4 razor)
<div id='cssmenu'>
<ul>
<li class="has-sub"><a href='#'><span>submenu</span></a>
<ul class="subbg">
<li><span>aaaa</span></li>
<li><span>bbbb</span></li>
<li><span>cccc</span></li>
<li><span>ddddd</span></li>
</ul>
</li>
<li><span>wwww</span></li>
</ul>
</div>

jQuery slide down navigation

I'm trying to build a simple jQuery slide down navigation but I'm having a bit of a issue with toggle in on and off the navigation.
I have navigation as follows.
<ul id="nav">
<li>home</li>
<li class="parent">Clothing
<ul>
<li>child</li>
<li>child</li>
<li>child</li>
</ul>
</li>
<li class="parent">shoes
<ul>
<li>child</li>
<li>child</li>
<li>child
<ul>
<li>child child</li>
</ul>
</li>
</ul>
</li>
with the following jquery
var $j = jQuery.noConflict();
$j(document).ready(function() {
$j('#nav').children('.parent').click(function(e){
e.preventDefault();
$this = $j(this);
$j('#nav').children('.parent').children('ul').stop().slideUp('slow', function(){
$this.children('ul').stop().slideToggle('slow');
});
});
});
Now when i click the Sub navigation slides out, clicking again does nothing, and i need it to slide back up. If i click another one what I need to happen is have the expanded nav (if any) slide back up, and then the new one slide down after, but it's just not wanting to work correctly for me! It's buggy and both display at once, and sometimes don't show.
See this...
var $j = jQuery.noConflict();
$j(document).ready(function() {
$j('#nav > .parent').on('click', function(e){
e.preventDefault();
$j('#nav > .parent').children().stop().slideUp('slow');
$j(this).children().stop().slideToggle('slow');
});
});
See this jSfiddle example

Categories