Removing active state when toggling between divs - javascript

I have created multiple top down menu items. When the links are clicked a div slides down to show some content.
What I am trying to do with these links is toggle between them. When one div is opened an active state is added to the link, when it is closed the active state is removed and the div hidden. When you click between the links I have managed to get them to toggle between each other and the active state is added to the div that is opened.
What I cannot achieve is removing the active state and resetting some css.
Here is my Javascript:
//menu toggle
$(".trigger").click(function() {
var divToToggle = $( $(this).data('target') );
$(".toggle:visible").not(divToToggle).hide();
$(".trigger").not(divToToggle).removeClass('active');
$('.top-nav').css('margin-top', '20px');
divToToggle.slideToggle("fast", "linear");
$(this).toggleClass('active');
$('.top-nav').css('margin-top', '0px');
return false;
});
The .toggle class is on all the divs that are toggled:
<div class="account-container toggle hide"></div>
<div class="collections-container toggle hide"></div>
<div class="search-container toggle hide"></div>
The .trigger class is on all my links:
<ul class="top-nav">
<li><a class="hidden-tablet" href="">home </a></li>
<li><a class="hidden-tablet" href="">about us </a></li>
<li><a class="hidden-tablet" href="">where to buy </a></li>
<li><a class="hidden-tablet" href="">contact us </a></li>
<li class="tablet-menu visible-tablet"><a class="tablet-menu trigger" href="" data-target=".tablet-menu-container">tablet menu</a></li>
<li class="account"><a class="account trigger" href="" data-target=".account-container">account</a></li>
<li class="collection"><a class="collection trigger" href="" data-target=".collections-container">collections</a></li>
<li class="search"><a class="search trigger" href="" data-target=".search-container">search</a></li>
<li class="basket"><a class="basket trigger" href="" data-target=".home-basket-container">basket</a></li>
</ul>

It's hard to say where exactly your code is going wrong, but I've re-written it so it works slightly differently. Your click handler has to handle two possibilities: either we're clicking to hide an existing section, or we're clicking to switch to a new section. But we can also think of this as being two steps, with the second one optional: either we hide an existing section, or we hide an existing section and show a new one.
I've also switched to using ev.preventDefault() to stop the link from firing, named the jQuery variables so they start with $ (which makes them easier to differentiate). You can try it out on jsfiddle here.
$(document).ready(function () {
$(".trigger").click(function (ev) {
ev.preventDefault();
var $clickedLink = $(this);
var $divToToggle = $($(this).data('target'));
var isHideOnly = $clickedLink.hasClass('active');
// Hide the existing div and remove 'active' class.
$(".toggle:visible").hide();
$(".trigger").removeClass('active');
$('.top-nav').css('margin-top', '20px');
// If we're showing a new one, reveal it and set the active class on the link.
if (!isHideOnly) {
$divToToggle.slideToggle("fast", "linear");
$('.top-nav').css('margin-top', '0');
$clickedLink.addClass('active');
}
});
});

Related

Clicking outside of an element to hide it, doesn't work with multiple elements

I want to hide multiple navigation bars when clicked outside of it, it makes sense to do so, But only one of them hides for one obvious reason.
HTML:
<nav class="navigation">
<ul>
<li><b>Aken</b></li>
<li class="right dropdown">
<a href="#" class="navigation-link nav-trigger">
Akar Muhamad
<img class="profile-picture" src="http://placehold.it/30x30/3498db/333">
<i class="fa fa-caret-down" aria-hidden="true" style="position: relative; right: 3%;"></i>
</a>
<div class="dropdown-content">
Profile
Settings
Logout
</div>
</li>
<li class="right dropdown">
<a href="#" class="navigation-link nav-trigger">
Akar Muhamad
<img class="profile-picture" src="http://placehold.it/30x30/3498db/333">
<i class="fa fa-caret-down" aria-hidden="true" style="position: relative; right: 3%;"></i>
</a>
<div class="dropdown-content">
Profile
Settings
Logout
</div>
</li>
</ul>
</nav>
JS:
$('.nav-trigger').on('click', function() {
// Loop through all the drop-downs, and make all of them invisible
// Except the one we clicked on.
$(this).siblings('.dropdown-content').toggleClass('visible');
var that = this;
$('.dropdown').each(function() {
if (that != this) {
$(this).siblings('.dropdown-content').removeClass('visible');
}
});
});
// TODO: Fix a bug where it doesn't work on multiple navigation bars.
$(document).on('click', function(event) {
if(event.target !== $('.nav-trigger')[0]) {
$('.dropdown').each(function() {
$(this).find('.dropdown-content').removeClass('visible');
});
}
});
Now, as you can see, I passed 0 as an index to check. But what I want is to loop through all of them and use the index as the key to that. Whenever I do that, it doesn't work at all, It also disables the click to show the navigation content function too.
Here's the JSBin.
You actually don't have to use loops here and you don't need to know the index.
$('.nav-trigger').on('click', function() {
// remove visible class from each .dropdown-content:
$('.dropdown-content').removeClass('visible');
// add visible class to .dropdown-content next to the clicked .nav-trigger:
$(this).siblings('.dropdown-content').addClass('visible');
});
$(document).on('click', function(event) {
// check if the clicked element is .nav-trigger:
$(event.target).is('.nav-trigger') ||
// if not, remove visible class from each .dropdown-content:
$('.dropdown-content').removeClass('visible');
});
JSFiddle Demo
Remove the loops and simply hide all of the dropdowns. Then add back the one you care about if necessary.
This code stores the dropdown visibility at click and uses it to toggle the visibility after hiding the dropdown content. This means that clicking the header will both open and close the dropdown.
$('.nav-trigger').on('click', function(event) {
// store current dropdown state
var visible = $(this).siblings('.dropdown-content').hasClass('visible');
// hide all dropdowns
$('.dropdown .dropdown-content').removeClass('visible');
// if we were visible, hide, and vice-versa
$(this).siblings('.dropdown-content').toggleClass('visible', !visible);
// prevent document handler from being fired
event.stopPropagation();
});
// hide all dropdowns if click propagates to document
$(document).on('click', function(event) {
$('.dropdown .dropdown-content').removeClass('visible');
});
JSBin

Jquery - How to add active class to entire navigation menu path?

I have a menu with 3 levels, and I would like to use a class for the first active li and a second class for all other subsequent li. When I click on a selection the level 3 to remain active the whole path (level 1, level 2, level 3). If I click on a selection on level 2 to remain active up to level 2.
I have the following:
$(document).ready(function(){
$('.sf-menu li a').each(function(index) {
if((this.pathname.trim() == window.location.pathname))
$(this).parent().addClass("selected");
var next_li = $(this).parent().next();
$('a', next_li).addClass("selected2");
});
});
I think I got it this time, It's a bit dirty but It works.
First add classes so you can identify first, second and third level <li> elements. Do it in the foreach, or whatever bucle that makes the menu (or by hand if there's no such bucle):
<ul id="navlist" >
<li id="home" class="firstLevel">
<a class="nav" href="home">Home</a>
<ul class="secondLevel">
<li class="secondLevel">
<a class="nav2" href="home">sub-Home1</a>
<ul>
<li class="thirdLevel"><a class="nav3" href="home">sub-sub-Home1></a></li>
<li class="thirdLevel"><a class="nav3" href="home">sub-sub-Home1></a></li>
</ul>
</li>
<li><a class="nav2" href="home">sub-Home2</a></li>
</ul>
</li>
<li id="about" class="firstLevel">
<a class="nav" href="about-us">About Us</a>
</li>
</ul>
Then use jQuery closest. It traverses up the DOM tree and matches the closest item, you can pass a selector (the firstLevel or secondLevel classes we just created):
$('#navlist a').on('click', function (e) {
e.preventDefault(); //prevent the link from being followed
$('#navlist a').removeClass('selected');
$('#navlist a').removeClass('selected2');
$(this).closest('.secondLevel').children('a').addClass('selected2');
$(this).closest('.firstLevel').children('a').addClass('selected2');
$(this).addClass('selected');
});
Then you add !important to the selected class (so when there's a colision like in the About Us link selected is the class that is applied). This is the dirtiest part.
Check a working fiddle: https://jsfiddle.net/4r5vg/661/

Removing and adding Classes on Dropdown Menus on Hover

I have a Navigation built that have drop down menus,
HTML STRUCTURE LIKE SO
<li class="c-header__subnav-item c-header__subnav-item-is-hidden c-header__subnav-item-is-visible-md">
<a class="c-header__subnav-links u-caps js-c-header__subnav-trigger" href="#">
Action Review Review
<i class="fa fa-angle-down fa-lg c-btn__icon-right-sm"></i>
</a>
<ul class="c-header__subnav-dd">
<li class="c-header__subnav-dd-item">
<a class="c-header__subnav-links c-header__subnav-links--dd" href="#">
Overview
</a>
</li>
<li class="c-header__subnav-dd-item">
<a class="c-header__subnav-links c-header__subnav-links--dd" href="#">
Review Form
</a>
</li>
<li class="c-header__subnav-dd-item">
<a class="c-header__subnav-links c-header__subnav-links--dd" href="#">
Performance Card
</a>
</li>
<li class="c-header__subnav-dd-item">
<a class="c-header__subnav-links c-header__subnav-links--dd" href="#">
Recent Recordings
</a>
</li>
</ul>
</li>
When You Hover On the a.js-c-header__subnav-trigger
It addes a class to its self as well as its sibling ul ( the dropdown menu)
This is perfect but since the hover is triggered on the 'a' element If I toggle the class when and I go to hover on the drop down menu it gets removed before I can because of hovering off the 'a' element.
If I just add the classes and do not use toggle how would I remove both classes once I hover off the A element or Dropdown menu.
What needs to be achieved is
1.) If main nav link is hovered add an active class to itself and drop down is triggered and can be seen. If you hover out WITHOUT engaging the dropdown both active and dropdown class are removed
2.) If main nav link is hovered add an active class to itself and if dropdown IS engaged by user keep both classes until dropdown is hovered out of or 'A' Element.
CURRENT JQUERY CODE
;(function($, window, document, undefined) {
var $win = $(window);
var $doc = $(document);
var $classes = {
SubNavTrigger : 'js-c-header__subnav-trigger',
SubNavItemActive : 'c-header__subnav-item-is-active',
SubNavDropDown : 'c-header__subnav-dd',
SubNavDropDownActive : 'c-header__subnav-dd-is-active'
};
var _isMobile = false;
_isMobile = ($win.width() <= 1024) ? true : false;
// Check if user is on touch on page load
// if isMobile use click events
// if not mobile use hover events
if(_isMobile) {
$("." + $classes.SubNavTrigger).on('click', function(){
if ( $(this).hasClass( $classes.SubNavItemActive ) ){
// If Item has active class removeClass
$(this).removeClass( $classes.SubNavItemActive )
} else {
// If Item does not have active class addClass
$(this).addClass($classes.SubNavItemActive);
} //End if
// Add Active Class To Subnav.
$(this).siblings().toggleClass($classes.SubNavDropDownActive);
});
} else {
$("." + $classes.SubNavTrigger).on('hover', function(){
$(this).addClass($classes.SubNavItemActive);
// Add Active Class To Subnav.
// If set to toggle impossible to hover on this menu.
$(this).siblings().addClass($classes.SubNavDropDownActive);
});
}
})(jQuery, window, document);
Thanks In Advance for any help.
Live Site Link to see
http://100dc.vincebrown.me/integrity-pledge
So I would make a few changes, I would move the s-c-header__subnav-triggerclass to the parent li. I would then change the jquery to use the hover(in,out). The in function would look something like
function () {
$(this).addClass($classes.SubNavItemActive);
// Add Active Class To Subnav.
$(this).children().addClass($classes.SubNavDropDownActive);
}
and the out
function () {
$(this).removeClass($classes.SubNavItemActive);
// Add Active Class To Subnav.
$(this).children().removeClass($classes.SubNavDropDownActive);
}
Here is a jsfiddle

Add 3 active class at once with javascript

I have this code, and eberything works fine, and also add the active class like I want.
However, it's possible when i click on href='#tab58', add active in the first three classes at once?
If I click in <a class="section_010" href='#tab58'></a>
I Want to add active in this first class at once
<a class="section_010 active" href='#tab58'></a>
<a class="section_011 active" href='#tab58'></a>
<a class="section_012 active" href='#tab58'></a>
If I click on another href, work fine (only that item add active class)
Code EXAMPLE Here
$(document).ready(function () {
$('ul.prov').each(function(){
// For each set of tabs, we want to keep track of
// which tab is active and it's associated content
var $active, $content, $links = $(this).find('a');
// If the location.hash matches one of the links, use that as the active tab.
// If no match is found, use the first link as the initial active tab.
$active = $($links.filter('[href="'+location.hash+'"]')[0] || $links[0]);
$active.addClass('active');
$content = $($active.attr('href'));
// Hide the remaining content
$links.not($active).each(function () {
$($(this).attr('href')).hide();
});
// Bind the click event handler
$(this).on('click', 'a', function(e){
// Make the old tab inactive.
$active.removeClass('active');
$content.hide();
// Update the variables with the new link and content
$active = $(this);
$content = $($(this).attr('href'));
// Make the tab active.
$active.addClass('active');
$content.show();
// Prevent the anchor's default click action
e.preventDefault();
});
});
</script>
<ul class="prov">
<a class="section_010" href='#tab58'></a>
<a class="section_011" href='#tab58'></a>
<a class="section_012" href='#tab58'></a>
<a class="section_02" href='#tab60'></a>
<a class="section_03" href='#tab61'></a>
<a class="section_04" href='#tab62'></a>
<a class="section_05" href='#tab63'></a>
<a class="section_06" href='#tab64'></a>
<a class="section_07" href='#tab65'></a>
</ul>
<div class="mapa_legenda">
<div id='tab58'> TEXT1</div>
<div id='tab60'> TEXT2</div>
<div id='tab61'> TEXT3</div>
<div id='tab62'> TEXT4</div>
<div id='tab63'> TEXT4</div>
<div id='tab64'> TEXT4</div>
<div id='tab65'> TEXT4</div>
</div>
I update this code My Updated code
It's possible, when I click in "About MHG", "Workout Programs" OR "Fitness Tips". All of them , stay active at once. (you click in one of them, and all 3 stay active).
I only want that for "About MHG", "Workout Programs" OR "Fitness Tips"
Anyone could help me please?
<ul class="navi">
<li><a class="menu2" href="#">About MHG</a></li>
<li><a class="menu3" href="#">Workout Programs</a></li>
<li><a class="menu4" href="#">Fitness Tips</a></li>
<li><a class="menu5" href="#">Contact Us</a></li>
<li><a class="menu6" href="#">Read Our Blog</a></li>
</ul>
It's simple.
Please check
http://jsfiddle.net/9nd4j/1282/
Just add this part:
$(this).closest('ul').find('li a').each(function(i){
if (i<3)$(this).addClass('active');
});
Check this example, that I edit
I add active class, on both 3 first itens like you want.
Just using:
$('a.menu').click(function(){
$('a.menu').removeClass("active");
$('a.menu2').removeClass("active");
$(this).addClass("active");
});
$('a.menu2').click(function(){
$('a.menu2').removeClass("active");
$('a.menu').removeClass("active");
$('a.menu2').addClass("active");
});
Please check:
http://jsfiddle.net/9nd4j/1264/

Adding a class to an element which is not selected/focused

I have a button, when it is hovered i want to add a CSS class to another element. However i have multiple elements and only want to add it to a specific one.
Currently i have :
$("ul.subnav").parent().append("<span></span>"); //Only shows drop down trigger when js is enabled (Adds empty span tag after ul.subnav*)
var button = $('#loginButton');
button.hover(function (login) {
$("ul.navbar-nav li span").addClass("subhover");
}, function () { //On Hover Out
$("ul.navbar-nav li span").removeClass("subhover"); //On hover out, remove class "subhover"
});
This works, however it adds the class to all the elements.
<li>
<a id="loginButton">
<img class="IconStyle" src="Icons/loginIcon.ico"></img>
</a>
<ul class="subnav">
<li>
</li>
<li>
</li>
</ul>
<span class=""></span> // This is the element i want to add a class to.
The is what i would like to add the class to, however as i said there are 5 of these created programmatically
You could use toggleClass and in/out hover handler:
button.hover(function (login) {
$(this).closest('li').find('span').toggleClass("subhover");
});
Change your HTML to:
<li>
<a id="loginButton">
<img class="IconStyle" src="Icons/loginIcon.ico"></img>
</a>
<ul class="subnav">
<li>
</li>
<li>
</li>
</ul>
<span id = 'spanElement'></span>
and your JQuery to:
var button = $('#loginButton');
alert($("ul.navbar-nav li span").eq(1000000));
button.hover(function (login) {
$("#spanElement").addClass("subhover");
}, function () { //On Hover Out
$("#spanElement").removeClass("subhover"); //On hover out, remove class "subhover"
});

Categories

Resources