Is there a way to simplify this jquery? - javascript

I wrote a dropdown menu with the following structure. It is supposed to drop down on click, and close on click.
Here's the HTML
<ul id="nav" class="nav">
<li>
<a id="menu1" class="menu">MENU 1</a> <!-- top menu -->
<div id="submenu1" class="submenu"> <!-- hidden by default -->
SUBMENU ITEM 1 <!-- submenu item -->
SUBMENU ITEM 2
</div>
</li>
<li>
<a id="menu2" class="menu">MENU 2</a>
<div id="submenu2" class="submenu">
SUBMENU ITEM 1
SUBMENU ITEM 2
SUBMENU ITEM 2
</div>
</li>
</ul>
And that's the JavaScript (using jQuery)
$("#menu1").click(function() {
$("div.submenu").hide(); // hide all menus
$("#submenu1").toggle(); // open this menu
});
$("#menu2").click(function() {
$("div.submenu").hide(); // hide all menus
$("#submenu2").toggle(); // open this menu
});
$("#menu3").click(function() {
$("div.submenu").hide(); // hide all menus
$("#submenu3").toggle(); // open this menu
});
$("#menu4").click(function() {
$("div.submenu").hide(); // hide all menus
$("#submenu4").toggle(); // open this menu
});
$(document).bind('click', function(e) {
var $clicked = $(e.target);
if (! $clicked.parents().hasClass("nav"))
$("div.submenu").hide();
});
There is a lot of repetition in the first part of the JS, is there a way to make this shorter, nicer, better?

You should be able to reduce the script to:
$(".nav .menu").click(function() {
$("div.submenu").hide(); // hide all menus
$(this).next().toggle(); // open this menu
});
$(document).click(function(e) {
if (! $(e.target).parents().hasClass("nav"))
$("div.submenu").hide();
});

Yes:
var $submenus = $('.submenu');
$(".menu").click(function(e){
var $menu = $(this).next('.submenu').toggle();
$submenus.not('#' + $menu[0].id).hide();
e.preventDefault();
});
$(document).click(function(e){
if( !$(e.target).closest('.nav').length ) $submenus.hide();
});

Related

How to close mobile menu on click for anchor links

I need a help with mobile menu. I try to find/add some script which close menu after click on menu item. Can anybody help with.
My page is https://www.institut-vz.si/
So When you click on the menu link it's going to the section but the menu is still open. So I need some script it should close after clicking the menu link.
When you click on burger menu, "style" change from display:none to display:block, and menu item get class "inView current_page_item".
Any help please.
<nav id="main-menu" class="menu-header-menu-container">
<ul class="menu menu-toggle-open" style="display: block; overflow: visible;">
<li id="menu-item-16670" class="menu-item">Home</li>
<li id="menu-item-16673" class="menu-item inView current_page_item">Service</li>
<li id="menu-item-16676" class="menu-item">About us</li>
<li id="menu-item-16677" class="menu-item">Contact</li>
</ul>
Also mobile menu have this active JS code:
//Mobile Menu
$("#dt-menu-toggle").click(function( event ){
event.preventDefault();
var $menu = $("nav#main-menu").find("ul.menu:first");
$menu.slideToggle(function(){
$menu.css('overflow' , 'visible');
$menu.toggleClass('menu-toggle-open');
});
var $right = $("nav#main-menu").find("ul.menu-right");
if( $right.length ) {
$right.slideToggle(function(){
$right.css('overflow' , 'visible');
$right.toggleClass('menu-toggle-open');
});
}
});
Add this script in footer.php
jQuery(document).on("click",".menu-item", function(){
jQuery(".menu-item").closest(".menu").removeClass("menu-toggle-open").hide();
});

Bootstrap nav-tabs check for selected tab using jquery

I have the following Bootstrap nav tabs:
<div class="row spiff_tabs_body">
<!-- Nav tabs -->
<ul class="nav nav-tabs spiff_tabs" role="tablist">
<li role="presentation" class="active">
Potential Spiff
</li>
<li role="presentation">
Instant Spiff
</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="delayedspiff"></div>
<div role="tabpanel" class="tab-pane" id="instantspiff"></div>
</div>
</div>
</div>
</div>
I need to be able to check which tab is selected and then display an alert. I have the following javascript in my view:
<script>
$(function () {
FormGet('dashboard/delayedspiff', 'delayedspiff');
});
</script>
<script>
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
// here is the new selected tab id
var selectedTabId = e.target.id;
var id = $('.tab-content .active').attr('id');
if (id == "delayedspiff") {
alert("delayedspiff");
} else {
alert("instantspiff");
}
});
</script>
When I click the tabs it works, but the alert always displays delayedspiff. I need to dislay instantspiff when they click on the instantspiff tab. Can anyone see what I'm doing wrong?
You just need to remove class active from all tabs and add it to the tab which was clicked.
EDIT: In order to get the id of clicked tab, try using an attribute data-id on the tab selections.
<li role="presentation" class="active">
Potential Spiff
</li>
<li role="presentation">
Instant Spiff
</li>
<script>
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
var wrongid = $('.tab-content .active').attr('id');
$('a[data-toggle="tab"]').removeClass("active"); // remove class active from all tabs
$(this).addClass("active"); // add class active to the current tab
var correctid = $(this).data("id"); // get the attribute data-id of the clicked tab
alert($('.tab-content .active')[0].outerHTML); // shows why you are getting the incorrect id
if (correctid == "delayedspiff")
alert("delayedspiff");
else
alert("instantspiff");
});
</script>
Updated fiddle : https://jsfiddle.net/DTcHh/14313/

Navigation menu dropdown close on click

I am using bootstrap navigation menu with drop downs.On clicking one menu option its sub menus should open-thats done.Now on clicking the other menu dropdown,the previous one should close-thats done too.Now if the Home drop down is open with its sub menus and if i click on the Home dropdown again,it should close.THats what i want.
My code goes as:
<nav class="navbar easy-sidebar" >
<div class="sample">
<ul class="list-unstyled main-menu" ng-repeat="menu5 in indController.newArray">
<li class="dropdown">
<label class="navbar-collapse-btn" data-toggle="collapse" data-target=".{{menu5.mainMenu}}" id="nav-main">
{{menu5.mainMenu}}
<b class="menu-caret"></b>
</label>
<div class="{{menu5.mainMenu}} collapse" ng-repeat="menu1 in menu5.subMenus" >
{{menu1.sub_menu_title}}
</div>
</li>
</ul>
</div>
</nav>
//on clicking one dropdown,the other dd autocloses.
$('.sample').click(function () {
var $target = $($(this).data('target'));
if (!$target.hasClass('in')){
$('.sample .in').removeClass('in').height(0);
}
else{
$('.sample .in').addClass('in').height(0);
}
});
On click remove all classes 'in' or which one makes your menu opened. something like this:
$('.dropdown').on('click', function(){
$('.in').removeClass('in');
// other things..
});
Don't use height in jquery to do this work, better to use classes.

Special Drop-Down Menu

I am trying to achieve a simple drop-down menu with the following HTML structure. This structure is mandatory (I think) as explained in the illustrations below.
<nav role="navigation">
<ul id="main-menu" class="nav top-nav clearfix">
<li id="menu-item-1" class="menu-item">Menu 1</li>
<li id="menu-item-2" class="menu-item">Menu 2</li>
<li id="menu-item-3" class="menu-item">Menu 3</li>
</ul>
<ul id="sub-menu-1" class="sub-menu nav clearfix">
<li class="menu-item">Sub Menu 1.1</li>
<li class="menu-item">Sub Menu 1.2</li>
<li class="menu-item"><a href="#">Sub Menu 1.3/a></li>
</ul>
<ul id="sub-menu-2" class="sub-menu nav clearfix">
<li class="menu-item">Sub Menu 2.1</li>
<li class="menu-item">Sub Menu 2.2</li>
<li class="menu-item"><a href="#">Sub Menu 2.3/a></li>
</ul>
</nav>
To get a better idea of what I am trying to achieve I've made the following illustrations:
Simple menu with items arranged with inline blocks. As you can see, the menu scales to 100% of the container and has all the items arranged in center.
When hovering over a menu item which has a submenu. In the illustration that's Menu 1 which has Sub Menu 1 and it needs to display it on mouse hover, like a simple <ul><li><ul></ul></li></ul> would do. As you can see the submenu has to scale to 100% of the container and has all the items arranged in center.
I think the best approach is with javascript (not sure you can do this with only CSS), but I am kind off stuck. The sub menu appears on main menu item hover, but as soon as I hover out into the sub menu in order to navigate, the sub menu disappears. Anyway, this is the javascript:
$('nav #main-menu .menu-item a').hover(
function() {
var id = $(this).parent().attr('id');
id = id.substr(id.length - 1);
submenu = $('#sub-menu-' + id);
submenu.show();
},
function() {
var id = $(this).parent().attr('id');
id = id.substr(id.length - 1);
submenu = $('#sub-menu-' + id);
submenu.hide();
}
);
I am pretty sure that there is a better way to do this.
I've also set up a FIDDLE for better understanding.
//show sub menu when we hover over an item
$('nav #main-menu > .menu-item')
.on('mouseenter', function() {
$('.sub-menu').hide();
var id = $(this).attr('id');
id = id.substr(id.length - 1);
$('#sub-menu-' + id).show();
});
//hide submenu when the mouse goes away
$('nav').on('mouseleave', function() { $('.sub-menu').hide(); });
Modified your fiddle here: http://jsfiddle.net/3z8MR/10/
Edit
Add this line to conform to your specs in the comments
$('.sub-menu').on('mouseleave', function() { $(this).hide(); });

jquery - when toggle children do not toggle parent

I want to create a java-script-Drop-Down-Menu for a mobile site.
The problem is, that when I click on a list-item in level2, by the toggle of level1 the list-item of level2 (and level3) gets closed, so I have to click at the list-item of level1 again to see level2 and level3. How can I deactivate the toggle of level1 if I click on a list-item of level2?
Please point me to the right direction. Thank you!
Here's my html:
<div id="menu">
<ul>
<li class="level1"><a href="/xyz.html">
<li class="level1"><a href="/xyz.html">
<ul>
<li class="level2"><a href="/xyz.html">
<li class="level2"><a href="/xyz.html">
<ul>
<li class="level3"><a href="/xyz.html">
<li class="level3"><a href="/xyz.html">
</ul>
<li class="level2"><a href="/xyz.html">
</ul>
<li class="level1">
<li class="level1">
</ul>
</div>
Here's my jquery:
$(document).on('pageinit',function(e,data){
// close menu if you go to another page
$('#menu').hide();
$('.level2').hide();
$('.level3').hide();
// Do not link if a sub-menu is present
$('li:has(ul) > a').replaceWith(function() {
return $(this).text();
});
// at click on menu-button scroll to top and open menu
$(document).off('click', '#menuicon').on('click', '#menuicon',function(e) {
$('html, body').stop().animate({ scrollTop : 0 }, 0);
$('#menu').slideToggle(400);
});
// elements of the menu, different sub-menus width different classes
$('#menu').on('click','.level1',function(e) {
$(this).find('.level2').slideToggle();
});
$('#menu').on('click','.level2',function(e) {
$(this).find('.level3').slideToggle();
});
$('#menu').on('click','.level3',function(e) {
$('.level3').hide();
$('.level2').hide();
$('.level1').hide();
$('#menu').hide();
});
});
use e.stopPropagation();
$('#menu').on('click','.level1',function(e) {
e.stopPropagation();
$(this).find('.level2').slideToggle();
});
$('#menu').on('click','.level2',function(e) {
e.stopPropagation();
$(this).find('.level3').slideToggle();
});
$('#menu').on('click','.level3',function(e) {
e.stopPropagation();
$('.level3').hide();
$('.level2').hide();
$('.level1').hide();
$('#menu').hide();
});

Categories

Resources