onclick function requires double click because of class assignment delay - javascript

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).

Related

Jquery function add/remove class from div on button hover

I have this jquery script that I got some help with in creating in order to add/remove an "active" class to a div when hovering over a button.
Below a CodePen of what I have put together:
CodePen Link: https://codepen.io/dustin-keeslar/pen/dapLWM
It works well, however what I'm trying to change is to have whatever button was last hovered on, to keep the "active" class on the content. So that the content only changes when a different button is hovered over.
jQuery(document).ready(function() {
jQuery(".toggle-button").hover(function() {
var target = jQuery(this).data("target");
if (jQuery(this).hasClass("expand")) {
jQuery(this).toggleClass("expand");
jQuery("#" + target).removeClass("active");
} else {
jQuery(".toggle-button").removeClass("expand");
jQuery(".hidden-content").removeClass("active");
jQuery(this).toggleClass('expand');
jQuery("#" + target).toggleClass("active");
}
});
});
This will find a button that has data-target=content1" for example, and when it is hovered over it will toggle an "active" class to a div with the ID "content1". The problem is that when you are no longer hovering, everything disappears. I need the most recent hovered button to keep the "active" class on the content. But I also need the content to change dynamically when the next button is hovered over.
Then fix it to use mouseenter, and move your remove code to the top to remove your classes before adding them back to the element that's been entered. I don't understand exactly what you're trying to do here, but using mouseenter it should be something like:
jQuery(document).ready(function() {
jQuery(".toggle-button").mouseenter(function() {
jQuery(".toggle-button").removeClass("expand");
// jQuery(".hidden-content").removeClass("active");
$(".active").removeClass("active");
var target = jQuery(this).data("target");
jQuery("#" + target).addClass("active");
if (jQuery(this).hasClass("expand")) {
jQuery(this).removeClass("expand");
jQuery("#" + target).removeClass("active");
}
});
});
All you are missing is a check, to ensure the current item matches the target:
jQuery(this).attr('id') == target
Codepen here: https://codepen.io/anon/pen/VgKOPy

jQuery program not working

I am having a problem using jQuery, merely due to inexperience using it. My program is meant to give the CSS class current to the links in my navbar if they are clicked, and remove the class from the previous owner of it.
Keep in mind I am very inexperienced in javascript, only picking it up in a few minutes for the sake of a school assignment.The script is simply not doing anything.
My Code:
$(document).ready(function() {
$('a').click( function(i){
var $current = $('a.current');
$(this).addClass('current');
$current.removeClass('current');
});
});
Edit 1: Strange bug, current class is applied to the whole document if I do not click a link, but instead click the document.
You should first remove the class, and then add it. Otherwise you will not have a class added if you click an anchor twice.
$(function() {
$('a').click(function() {
$('a.current').removeClass('current');
$(this).addClass('current');
});
});
Try this:
$current.removeClass('current');
$(this).addClass('current');
You need to first remove the active class, then add the current class for the current element.
You need to narrow down your code to only affect the links in the nav bar, as currently, you are targetting all <a> tags.
var navLink = $('.nav a');
navLink.on('click', function(e){
navLink.removeClass('current');
$(this).addClass('current');
});
In this code, the variable gets all instances of the nav links, and if one of them is clicked, will remove the current class from all of the links before adding it onto the one that was clicked.
This jsfiddle will show you it in action: https://jsfiddle.net/td48vcqy/

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!

li nav menu only firing my .toggleClass every other click

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>

Toggle class on div = Untoggle class on another div

I have some divs (#div1, #div2, #div3) that change appearence on click, they toggle a class using this script:
$(document).ready(function() {
$("#parent_div").on('click', '.current_class', function () {
$(this).toggleClass("new_class");
});
});
Now I want the the divs to be unable to toggle at the same time, so they work kinda like a radio-button with same "name".
Example: Imagine three divs that looks the same (default class), then you click on one of the divs (example #div1) and that one toggles a new class and change appearence. Now you click on one of the other two and this one also change appearence (toggle class), at the same time when this one change appearence #div1 changes back to the default class.
So there can only be one div of those three that toggles the new class at once.
Is this possible?
You first need to remove the class from all the divs, and then add it to the current one. Try this:
$("#parent_div").on('click', '.current_class', function () {
$('#parent_div .new_class').removeClass('new_class'); // remove exisiting
$(this).addClass("new_class"); // add to current
});
Update
Added functionality to remove class from current:
$("#parent_div").on('click', '.current_class', function () {
var $this = $(this);
if (!$this.hasClass('new_class')) {
$('#parent_div .new_class').removeClass('new_class');
$this.addClass("new_class");
}
else {
$this.removeClass("new_class");
}
});
Use:
$(document).ready(function() {
$("#parent_div").on('click', '.current_class', function (){
if($(this).hasClass('.new_class')){
$(this).removeClass('.new_class');
}else {
$('.new_class').removeClass('.new_class');
$(this).addClass('.new_class');
}
});
});
Updated: Code now allows for toggling of current element with class .new_class.
This would be possible, but you'll need to reset all the other divs manually.
An example would be :
I have 3 divs available with id's div-1, div-2 and div-3.
I'm using a default class 'default' and a definition class so i can click them 'clickable', and my other class would be 'selected'.
To implement this you would need to do the following:
$(document).ready(function() {
$('#parent-div').on('click, 'clickable', function() {
$('.selected').removeClass("selected").addClass("default");
$(this).addClass("selected");
})
});
I hope this helps.
I didn't have the possibility to check if the syntax is exactly correct, but I believe this does the job as required.
Kind regards,
NDakotaBE

Categories