li nav menu only firing my .toggleClass every other click - javascript

So, I have a <ul> <li> jQuery Nav. The usual type. (mark-up wise).
Below is the jQuery that is powering it.. the problem is.. my .toggleClass only is read first click and third click (so every other click). So class doesn't attach on second click. Though, it does work properly on every click if the user hits the close button and that code fires.. But if the user doesn't 'close' and decides to go straight to the other nav item (which is more often the case). Every other click; everything is broken, because this line doesn't attach vv
$('section.educator-guide').toggleClass('toggle-margin'); // only attaches every other click
Below is all relevant jQuery.
$('.mainseries li').filter(':parent').click(
function(e){
//e.preventDefault();
$('.serieDetails').hide();
$('.mainseries li').removeClass('activeSerie');
$('.series').css('height','inherit');
$('section.educator-guide').toggleClass('toggle-margin'); // this
var element = $(this).find('.serieDetails');
element.fadeIn();
$('.series').height($('.series').height()+element.height());
$(this).addClass('activeSerie');
// $(this).toggleClass('toggle-margin');
$('html,body').animate({
scrollTop: $('.series').offset().top+element.height()} ,
'slow' ,
function(){
//element.show();
//$(this).find('.serieDetails').show();
});
});
$('.btnClose').click(function(e){
$('.mainseries li').removeClass('activeSerie');
$('section.educator-guide').removeClass('toggle-margin');
$('.serieDetails').slideUp("slow",function(){ $('.series').css('height','inherit'); $('.serieDetails').hide(); run=true;});
return false;
});
I have tried every which way of rearranging where I am calling this -- I have tried to .removeClass as the close button at the top of main <li> click function, still didn't work. I have tried adding return false; nothing!

toggleClass, as it name implies, toggles a class on or off.
Description: Add or remove one or more classes from each element in
the set of matched elements, depending on either the class's presence
or the value of the state argument.
for instance if you have
<a class="someClass"></a>
and call
$("a").toggleClass("someClass");
//resulting in <a class=""></a>
someClass will be removed.
Call toggleClass again and it adds it back.
$("a").toggleClass("someClass");
//resulting in <a class="someClass"></a>
If you need a class added every single time just use the addClass method.
Of course you could also just use toggleClass inside your close function, as well as in your open function, ie:
$('.btnClose').click(function(e){
...
$('section.educator-guide').toggleClass('toggle-margin');
...
});
This would toggle the class off when you close, and then toggle it back on when you open. But this has a disadvantage that at some point the state of the class might become backward, ie hitting close would toggle the class on, hitting open would toggle the class off. So in this particular case I would use addClass and removeClass
toggleClass Demo
jQuery("div").click(function(){
jQuery(this).toggleClass("toggled");
})
div {
background:#000;
color:white;
cursor:pointer;
}
.toggled {
background:#FFF;
color:black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="">Click me to toggle class on and off</div>

Related

jQuery collapsible through toggleClass on element

I have an off canvas navigation menu (classname that is enabled via hover-over using jQuery on my Wordpress site. It is, as it should be, not visible on page load.
For the mobile version, I want the same nav menu to be activated by clicking on a menu icon (that I've given two classes, in this order: mobile-nav-toggle show-nav-mobile). The toggle method seems to only work for a vertical toggle. My solution to replicating the same animation on click rather than hover, is by using the toggleClass method on the icon to toggle between a classname that opens the menu nav (show-nav-mobile) and closes it (hide-nav-mobile) Using the below code:
jQuery(".show-nav-mobile").click(function(){
jQuery(".offcanvasmainnav").animate({left:'0px' }, 250);
});
jQuery(".mobile-nav-toggle").click(function(){
jQuery(".mobile-nav-toggle").toggleClass("show-nav-mobile hide-nav-mobile");
});
jQuery(".hide-nav-mobile").click(function(){
jQuery(".offcanvasmainnav").animate({left:'-640px' }, 250);
});
That doesn't seem to do the job though. The jQuery opens the offcanvasmain div just fine, but doesn't close it again.
What is wrong with my approach?
I assume your element initially looks somewhat like this:
<nav class="mobile-nav-toggle hide-nav-mobile">...</nav>
This means that
a) Both these click handlers will always run when clicking, no matter if the element still has the class hide-nav-mobile:
jQuery(".mobile-nav-toggle").click(function(){
jQuery(".mobile-nav-toggle").toggleClass("show-nav-mobile hide-nav-mobile");
});
jQuery(".hide-nav-mobile").click(function(){
jQuery(".offcanvasmainnav").animate({left:'-640px' }, 250);
});
jQuery finds the element at the moment you define the click handler; it doesn't recheck if the element still has this class when clicking later.
b) This never attaches a click handler:
jQuery(".show-nav-mobile").click(function(){
jQuery(".offcanvasmainnav").animate({left:'0px' }, 250);
});
because at the time of calling jQuery(".show-nav-mobile") it cannot find any element with that class.
To fix it, do this all in a single click handler:
jQuery(".mobile-nav-toggle").on('click', function(){
const that = jQuery(this);
that.toggleClass("show-nav-mobile hide-nav-mobile");
jQuery(".offcanvasmainnav").animate({left: that.hasClass('show-nav-mobile') ? '0px' : '-640px' }, 250);
});

onclick function requires double click because of class assignment delay

The title says it all. I got a list of LI elements. When clicked on navigation the active li gets a class 'current' but this takes a second.
But when I use my code I need to click on the nav then the li opens and I need to click again to make the code register.
The place of the videos cannot be hardcoded! It needs to be dynamic.
(function($) {
$(document).ready(function(){
$('video').each(function() {
$(this).get(0).pause();
});
$('.slides').children('li').addClass('test');
});
$(document).on('click','span',function(){
if ( $('li').hasClass('current') ) {
$('li.test').find('video').each(function() {
$(this).get(0).pause();
});
$('li.current.test').find('video').each(function() {
$(this).get(0).play();
});
}
});
})(jQuery);
http://codepen.io/hennysmafter/pen/aNrVKG?editors=1010
Unfortunately I won't be available for the next hour or so but will be back after that! Everyone thank you for helping.
I found what is causing the issue :
You are playing the elements whose parent has ".current" class when a span is clicked.
But when you click an element, it et the ".show" class, and the previously selected span get the ".hide" class AND keeps the ".current" class, until the animation is finished (then the ".show" & ".hide" class are removed and the ".current" class switch elements).
One solution is changing the selectors like this :
$(document).on('click','span',function(){
console.log('the if is running');
$('.current, .hide').find('video').each(function() {
$(this).get(0).pause();
});
$('.show').find('video').each(function() {
$(this).get(0).play();
});
});
By doing this, whenever a span is clicked, you pause the element whose parents have the ".hide" class, and play the ones whose parents have the ".show" class.
Another solution should be creating an event when a class is applied (See jQuery - Fire event if CSS class changed).

Animate icon don't take his original position on toggle click

I have a accordion menu which have for each parent menu a icon, and this icon is animated with css transition and transform. I added a class with a if condition to the click event. The problem is that when I click for example on Menu1, the icon animation does very well, but if I click directly on Menu2, the menu2 dropdown appear but icon from the menu1 don't take his original position.
This problem applies to each icon in each menu/submenu, I thinks that I have a mistake in my code.
$(document).ready(function() {
// Icons effect
$('#mw_nav .toggle').click(function() {
if($(this).hasClass('rotate_close'))
{
$(this).addClass('rotate_open').removeClass('rotate_close');
}
else {
$(this).addClass('rotate_close').removeClass('rotate_open');
}
});
// Toggle Menu Items
$(function () {
$("#m_nav > ul ul").hide();
$('#m_nav .toggle').click(function (e) {
e.preventDefault();
e.stopPropagation();
var $parentli = $(this).closest('li');
$parentli.siblings('li').find('ul:visible').slideToggle(400);
$parentli.find('> ul').stop().slideToggle(400);
$(this).remove;
});
});
});
FIDDLE
Any help would be appreciated
There are 2 issues I see with your code. The first is a recommendation to NOT have $(function() { // your code }) inside of $(document).ready(). $(function() {}) is actually just shorthand for $(document).ready() so you are adding code you do not need.
The second is an issue with your logic.
$('#mw_nav .toggle') and $('#m_nav .toggle') click listeners are essentially adding a click listener on the same exact element, but both run different logic. When the $('#mw_nav .toggle') click listener is getting called it checks for a class to exist to decide what class it needs to remove and add. When $('#m_nav .toggle') click listener is getting called it calls a slideToggle function on the current nested <ul> regardless if another menu is opened or closed and there is no check in place of whether or not the rotate_open/rotate_close classes exist allowing for the classes to get swapped. There is no relation between the swapping of rotate_open/rotate_close classes and the logic that slideToggles <ul> up/down.
UPDATE
I have edited your code and made updates that will now work seen here: https://jsfiddle.net/vhfn0q5a/9/
I have added a class of .top_level to the top level items in your HTML. I use this as a way of differentiating the top level <li> from the sub menus. Next, at the end of the click event listener I check to see if the .toggle element clicked is a top level element, if so I target all top level elements that are not the current selected and make sure they have the .rotate_close class.
$(function() {}) shorthand reference
Use this code in your first click handler:
$('#mw_nav .toggle').click(function() {
$(this).toggleClass('rotate_close rotate_open');
if ($('#mw_nav .toggle').not(this).hasClass('rotate_open')) {
$('#mw_nav .toggle').not(this).removeClass('rotate_open').addClass('rotate_close');
}
});
I've updated your FIDDLE with an working example.
Cheers!

Once menu item is clicked, close menu and revert the classnames & jquery

Ok... So I have this drop down menu working as I'd like... however I'm trying to figure out how to revert the function back to it's original state after a menu item is clicked.
So first when you trigger the function it does & works great the following:
It swaps out .menu_hide and .lockscreen for .menu_show and .lockscreen_on.
// show and hide mobile menu
$('#triggerMobileMenu').click(function(e) {
e.preventDefault();
// Toggle all 4 classes off or on
$('#mobileMenu').toggleClass('menu_hide menu_show');
$('#mobileScreen').toggleClass('lockscreen_off lockscreen_on');
But now I'm trying to add another piece that says once a menu item is clicked, close the menu and swap the classes back to their original state from .menu_show and .lockscreen_on, to .menu_hide and .lockscreen_off.
$('#mobileMenu ul li a').on('click',function(){
$('#mobileMenu').toggleClass('menu_show menu_hide')({ autoCloseOnClick: true });
$('#mobileScreen').toggleClass('lockscreen_on lockscreen_off')({ autoCloseOnClick: true });
});
});
I should also note that on the same page a scroll to id# may be happening vs just simply taking you to the new url/page. Either case will happen though.
I think that you're making this too complicated. Use the same event handler for both a#triggerMobileMenu and ul#mobileMenu li a since you're having them do the same thing (toggle the visibility of the menu and another element).
$('a#triggerMobileMenu, ul#mobileMenu li a').on('click', function(evt){
evt.preventDefault();
$('#mobileMenu').toggleClass('menu_hide menu_show');
$('#mobileScreen').toggleClass('lockscreen_off lockscreen_on');
});
If you need to know which element was clicked in the event handler, evt.target is available:
if( $(evt.target).is($('a#triggerMobileMenu')) ) {
// do stuff
}
See http://jsfiddle.net/Mph6t/3/
I think it is working as intended. I had to fix some id names that may have been switched in the translation to jsfiddle. Here's a working one as far as I can tell. This leaves the somename2 div still showing. I assume that is going to be blank and just for locking the screen right?
I also changed the link to a new tab for testing purposes. FYI.
Relevant changes are:
$('#somename1 ul li a').on('click',function(){
$('#somename1').toggleClass('menu_show menu_hide')({ autoCloseOnClick: true });
$('#somename2').toggleClass('lockscreen_on lockscreen_off')({ autoCloseOnClick: true });
});

Set back again the current menu link to "active" once navigation through menu stops

Ok, maybe you can't understand much from the title, so I'll try to explain it a bit more in here.
Basically I have a navigation, like this:
<ul class="primaryNav">
<li class="nav1">About us</li>
<li class="nav2">Our world</li>
<li class="nav3">Active page</li>
</ul>
Now I'm on the "Active page" page and the "Active menu link" is active as you can see (the class is set manually by me on each page).
The user can navigate through that other menus (hover them) and they become active, and my "Active menu link" inactive and so on. (through jQuery)
Well, what I'm trying to do, is, once the user stops navigating through my menu, and move mouse cursor outside the navigation container (let's say), set back to "active" the "Active menu link" wich was initially active, with some timeout, maybe.
Hope I was clear enough about what I'm trying to achieve.
Thanks,
Adrian
Something like:
var resetMenu = function() {
$('li.active').attr('class','active').siblings().attr('class','inactive');
};
var to;
$('ul').bind('mouseout', function() {
window.clearTimeout(to);
to = window.setTimeout(resetMenu, 1000);
});
I'm using attr() instead of add/remove classnames here based on your example. You can alter the 1000 for more/less time to wait before "resetting" the menu.
I'm not completely clear what you want to do, but it sounds like you're looking for the jQuery hover() event, which fires when the mouse enters the matched element, and the callback function when it leaves.
$('ul.primaryNav').hover(function() {
// do stuff when the mouse enters the <ul>
},
function() {
// do stuff when the mouse leaves the <ul>
});
I suspect you might be intending to use <ul id="primaryNav"> and <li id="Nav1">, etc.—ids instead of classes to uniquely identify these elements.
What exactly // do stuff means depends on what exactly you're looking for, but probably just adding and removing an active class will do instead of using an inactive class as well.
I'm not looking for just the .hover() event from jQuery, it's little more than that.
I am already using jQuery .hover() event to add to the current hovered link the class "active" and to the others the class "inactive".
But in the Active page the "active" class from is set manually by me, and I want that to be active again when users stop navigation through my menu. I mean, when I play with the menu and hover the links it does the stuff I told you about (add class active to current, add class inactive to others) - when I mouseout the navigation area I want that the "active" class to "go" back again to the initial link who had that className when I first arrived into that page.
I have some submenus, also, wich are shown on hover, but I guess that's not so relevant for my question.
This should work. If you need explanations just comment on answer
var as;
var ul = $('ul.primaryNav').mouseout(function() {
toogle(
as.filter('.active'),
as.filter(function() {
return $(this).data('originalActive') === true;
})
);
});
as = ul.find('a');
//remember which one was original active
as.filter('.active').data('originalActive', true);
function toogle(ina, act) {
ina.removeClass('active').addClass('inactive');
act.removeClass('inactive').addClass('active');
};
as.mouseover(function() {
//make current active, inactive others
toogle(as.filter('.active'), $(this));
});

Categories