On my mobile site I've got a vertical dropdown menu (like an accordion) where each parent item features a down-pointing arrow to indicate the drop-down. When the user clicks on the parent item the arrow rotates and when you click it again to close the drop-down it rotates back to it's original state. However, if you don't click the drop-down to close it but just click on another parent item the drop-down closes, but the arrow stays in the rotated position.
Here is the code :
$('li.nav-about').click(function () {
$('#arrow-about').toggleClass("rotate");
$(this).find('ul').toggle();
});
$(' li.nav-industry').click(function () {
$('#arrow-indusrty').toggleClass("rotate");
$(this).find('ul').toggle();
});
$('li.nav-application').click(function () {
$('#arrow-application').toggleClass("rotate");
$(this).find('ul').toggle();
});
Any suggestions how to remove the 'rotate' class when another item is clicked?
EDIT
Here's what the mark up looks like :
<ul id="nav-list">
<li class="nav-list_item nav-about">About Us<div class="arrow-down" id="arrow-about"></div>
<ul>
<li>....</li>
<li>...</li>
<li>...</li>
</ul>
</li>
<li class="nav-list_item nav-products">Products<div class="arrow-down" id="arrow-products"></div>
<ul>
<li>....</li>
<li>...</li>
<li>...</li>
</ul>
</li>
You can remove the existent rotate class from every button before toggle the current like:
$('li.nav-about').click(function () {
$('.rotate:not("#arrow-about")').removeClass("rotate");
$('#arrow-about').toggleClass("rotate");
$(this).find('ul').toggle();
});
(' li.nav-industry').click(function () {
$('.rotate:not("#arrow-indusrty")').removeClass("rotate");
$('#arrow-indusrty').toggleClass("rotate");
$(this).find('ul').toggle();
});
$('li.nav-application').click(function () {
$('.rotate:not("#arrow-application")').removeClass("rotate");
$('#arrow-application').toggleClass("rotate");
$(this).find('ul').toggle();
});
If you don't want to change too much of your code, just try this.
$('li.nav-about').click(function () {
$('#arrow-about').toggleClass("rotate");
$('#arrow-indusrty').removeClass("rotate");
$('#arrow-application').removeClass("rotate");
$(this).find('ul').toggle();
});
$(' li.nav-industry').click(function () {
$('#arrow-about').removeClass("rotate");
$('#arrow-indusrty').toggleClass("rotate");
$('#arrow-application').removeClass("rotate");
$(this).find('ul').toggle();
});
$('li.nav-application').click(function () {
$('#arrow-about').removeClass("rotate");
$('#arrow-indusrty').removeClass("rotate");
$('#arrow-application').toggleClass("rotate");
$(this).find('ul').toggle();
});
Now you are sure that each element, instead of the selected one, will turn to their original state.
you could do this.
var toggleNavigation = function(){
var r_navigation = $('li.nav-about,li.nav-industry,li.nav-application');
$(r_navigation).each(function(i, oNav){
$(oNav).on('click',function(){
if(!$(oNav).hasClass('rotate')){
$(r_navigation).removeClass('rotate');
$(oNav).addClass('rotate');
}else{
$(oNav).removeClass('rotate');
}
});
});
};
Related
I have this problem with the shown.bs.dropdown event handler for the bootstrap dropdown. At the show event i set the animation class and i want that after the animation is complete to remove the class. Unfortunately the event is firing immediately after the show event.
I tried applying the class in the attribute at runtime (thought that this way bootstrap will be aware about the css transition to be applied and to delay the shown event) but with no result. The animation classes are provided by animate.css library. I set up a fiddle to show my issue. - http://jsfiddle.net/u08bt6ck/
Here is my markup:
<ul class="nav navbar-nav">
<li id="userMenu" class="dropdown">
Open me
<ul class="dropdown-menu">
<li><i class="fa fa-sliders"></i>lnk 1</li>
<li><i class="fa fa-user"></i>lnk 2</li>
<li><i class="fa fa-clock-o"></i>lnk 3</li>
</ul>
</li>
</ul>
And this is the js:
$('#userMenu').on({
"show.bs.dropdown": function () {
$('.dropdown-menu', this).addClass('animated fadeInDown');
},
"shown.bs.dropdown": function () {
$('.dropdown-menu', this).removeClass('animated fadeInDown');
},
"hide.bs.dropdown": function() {
$('.dropdown-menu', this).addClass('animated fadeOutDown');
},
"hidden.bs.dropdown": function () {
$('.dropdown-menu', this).removeClass('animated fadeOutDown');
//alert('ni ca s-a terminat');
}
});
For everyone having this problem i'll post here how i managed to work around this issue/problem.
Basically i set the fade in class when the user clicks and let it there until the menu is closing. If the menu starts to close, the fadeIn class is removed, the fadeOut class is added and after the animation is complete (handeled by the jquery .on([animationEndSelectors])) i remove the fadeOut class and close the submenu (by revmoving the open class on the ul).
var animationEndSelectors = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend';
var inAnimation = 'animated ' + 'fadeInDown';
var outAnimation = 'animated ' + 'fadeOutUp';
$('#userMenu').on({
"show.bs.dropdown": function () {
$('.dropdown-menu', this).addClass(inAnimation);
},
"hide.bs.dropdown": function() {
var ddl = this;
$(ddl).addClass('closing');
$('.dropdown-menu', this).removeClass(inAnimation);
$('.dropdown-menu', this).addClass(outAnimation);
$('.dropdown-menu', this).one(animationEndSelectors, function () {
$('.dropdown-menu', ddl).removeClass(outAnimation);
$(ddl).removeClass('open closing');
});
return false;
}
});
You just need to create delays for when the animation classes are added/removed. For the "hide" event, you'll need to prevent Bootstrap from hiding it too soon by manually removing the open class after your animation classes are added...
$('#userMenu').on({
"shown.bs.dropdown": function () {
$(this).find('.dropdown-menu').addClass('animated fadeInDown');
setTimeout(function(){
$('.dropdown-menu').removeClass('animated fadeInDown');
},1000);
},
"hide.bs.dropdown": function(e) {
e.preventDefault();
$(this).find('.dropdown-menu').addClass('animated fadeOutUp');
setTimeout(function(){
$('.dropdown-menu').removeClass('animated fadeOutUp').parent().removeClass('open');
},1000);
}
});
Demo: http://bootply.com/iZObFaEJwr
Try this way.
$('#userMenu').on({"show.bs.dropdown",function () {
$('.dropdown-menu').addClass('animated fadeInDown');
});
$('#userMenu').on({"shown.bs.dropdown",function () {
$('.dropdown-menu').removeClass('animated fadeInDown');
});
$('#userMenu').on({"hide.bs.dropdown",function() {
$('.dropdown-menu').addClass('animated fadeOutDown');
});
$('#userMenu').on({"hidden.bs.dropdown",function () {
$('.dropdown-menu').removeClass('animated fadeOutDown');
});
I had exactly the same problem and it made no sense why the dropdown events wouldn't fire for me properly; turns out that class="dropdown-toggle" in my <a> element interfered with its data-toggle="dropdown" attribute.
Why this is the case, no idea (probably a package issue I'm not willing to spend more time delving into), but removal of this class did it for me; no need for all those crazy manual animation class hacks in the events.
I am building a registration system and I have a progress bar and a bootstrap nav-tabs in that page.
I am trying to setup the JQuery so that the progress bar advances with the nav-tabs. Here is a visual.
I tried to come up with a simple if else conditional jquery using hasClass and addCLass functions but never got to make a dent.
Something like this:
$(document).ready(function () {
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
if (".nav-tabs") hasClass(".active"); {
$(".checkout-bar li").addClass("active");
}
});
});
I am attaching a CODEPEN
Any idea on how to do this client side? I'd rather keep C# out of this one
http://jsfiddle.net/o3637uwh/2/ (update)
in html remove class form all checkout-bar li, except first
HTML
<ul class="checkout-bar">
<li class="active">Get Started</li>
<li class="">About You</li>
<li class="">Looking For</li>
<li class="">Review</li>
</ul>
JQ (update)
$(document).ready(function () {
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
var href = $(e.target).attr('href');
var $curr = $(".checkout-bar a[href='" + href + "']").parent();
$('.checkout-bar li').removeClass();
$curr.addClass("active");
$curr.prevAll().addClass("visited");
});
});
You are not specifying which .checkout-bar li to select. You have to get the index of the .active tab and with this index select the checkount li, I think you shoud do something like this:
$(document).ready(function () {
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
activeTabIndex = $('.nav.nav-tabs > li.active ').index();
(".checkout-bar li.active").removeClass('active');
$(".checkout-bar li:eq("+activeTabIndex+")").addClass('active')
});
});
In a jQuery setting what is the best way to stop default propagation on the first click and show the submenu if the user is on the first click then restore the a link on the second click, or hide the currently displayed submenu if the users clicks on any other part of the page i have tried this with a few variations but none seem to work:
$('.nav-bar li:has(ul)').on('click', function () {
var CheckForClasssub = $('.nav-bar li ul').hasClass('subshow');
if (CheckForClasssub) {
$('.subshow').hide('slow').removeClass('subshow');
} else {
$('.nav-bar li').on('click', function () {
var thisflyout = $(this).find('.flyout');
$(thisflyout).toggle('slow').addClass('subshow');
});
}
});
this is my current menu structure:
<ul class="nav-bar">
<li>
google
<ul>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
<li>test</li>
</ul>
</li>
<li>google</li>
<li>google</li>
<li>google</li>
<li>google</li>
</ul>
currently clicking on class="flyout" toggles the sub menu, but i would love to use the whole link
/*UPDATE**/
Ok this works fine to display on first click then follow link on second but it doesn't hide if the page is clicked anywhere else...
$('.nav-bar li:has(ul)').on('click', function (e) {
var CheckForClasssub = $('.nav-bar li ul').hasClass('subshow');
if (CheckForClasssub) {
$('.subshow').hide('slow').removeClass('subshow');
} else {
var thisflyout = $(this).find('.flyout');
e.preventDefault();
$(thisflyout).show('slow').addClass('subshow');
}
});
/*UPDATE**/
To clarify requirments:
user clicks on menu item with both an A link as the parent and a submenu using
ul > li + a > ul > li
If this is the first click show submenu.
If second click direct through to the relvant a link.
If user has clicked once on menu item 1 showing the submenu but decided to click on another parent menu item with a submenu hide submenu 1 show submenu 2.
If user has clicked on menu item 1 and decides to click anywhere else on page that isn't a menu item with a submenu hide the open submenu....
var submenucheck = $('.nav-bar li ul');
var submenucheckli = $('.nav-bar li a');
showHide = false;
function checkforsubsopen() {
// body...
$.each(submenucheck, function(el) {
/* iterate through array or object */
if($(this).hasClass('subshow')){
showHide = true;
}
});
return showHide;
}
$('.nav-bar li:has(ul)').on('click', function(e) {
var CheckForClasssub = $('.nav-bar li ul').hasClass('subshow');
if(CheckForClasssub){
}
else{
var thisflyout = $(this).find('.flyout');
e.preventDefault();
$(thisflyout).show('slow').addClass('subshow');
}
});
$(document).on('click', function(){
checkforsubsopen();
if(showHide){
$('.subshow').hide('slow').removeClass('subshow');
}
console.log(showHide);
});
this is my html:
<ul>
<li>Milk</li>
<li>Bread</li>
<li class='fade'>Chips</li>
<li class='fade'>Socks</li>
</ul>
this is my js function:-
$("li").hover(
function () {
$(this).append($("<span> ***</span>"));
},
function () {
$(this).find("span:last").remove();
}
);
i want to this type of output:-
<ul>
<li>Milk</li>
<li>Bread</li>
<li class='fade'>Chips</li>
<li class='fade'>Socks</li>
<span> ***</span>
</ul>
here i am try to append one span in mouse hover on li.
its work perfect.
but i want to append only one time after last li.
thanks.
I found the example on the jQuery api manual, isn't this what you want?
$("li").hover(
function () {
$(this).append($("<span> ***</span>"));
},
function () {
$(this).find("span:last").remove();
}
);
Or you don't want to remove the span when mouse leave, and just want to append one span:
$("li").hover(function () {
if ($(this).find('span').length == 0) {
$(this).append($("<span> ***</span>"));
}
});
Use one:
$("li").one("hover", function () {
$(this).append($("<span> ***</span>"));
});
http://api.jquery.com/one/
Simply check first if the span already exists. Remember that 'hover' can take two functions if you want to remove the span after the mouse leaves. This is the equivalent to mouseover and mouseleave combined.
$("li").hover(
function () {
if ($(this).is(':empty')) {
$(this).append($("<span> ***</span>"));
}
});
References: hover, empty, mouseover, mouseleave
Use modern JS!
const lis = document.getElementsByTagName("li");
let span;
for (const li of lis) {
li.addEventListener("mouseover", function() {
// Do something cool
if (!span) {
span = document.createElement("span");
span.innerText = " ***";
li.parentElement.append(span);
}
}, {once : true}); // (optional) This will make it fire only once for each li
// You could add one "once" listener to just the ul as well
}
Documentation, CanIUse
I have a dropdown menu that slides up and down when toggled to reveal it's menu items. The problem is that when i go to click one of the menu items after the menu has slid down, it is recognized as a toggle and the menu slides up without opening the link of the menu item.
HTML
<li class="dropdown">
Carbohydrates, proteins & fats
<ul>
<li>Carbohydrates</li>
<li>Proteins</li>
<li>Fats</li>
</ul>
</li>
dropdown script:
$(document).ready(function () {
$('.dropdown').toggle(
function () {
//show its submenu
$('ul', this).slideDown(300);
},
function () {
//hide its submenu
$('ul', this).slideUp(300);
}
);
});
I'd appreciate any help with this.
Try moving the triggering link outside of the dropdown items
Carbohydrates, proteins & fats
<div class="divdropdown">
<ul>
<li>Carbohydrates</li>
<li>Proteins</li>
<li>Fats</li>
</ul>
</div>
And then slightly modify your jquery
$(document).ready(function () {
$('.dropdown').toggle(
function () {
//show its submenu
$('ul', $(".divdropdown")).slideDown(300);
},
function () {
//hide its submenu
$('ul', $(".divdropdown")).slideUp(300);
}
);
});
Why are you individually closing/opening the menu items? Everything gets hidden anyway when the parent <li> element is hidden -- why do anything after that?
I think you want to disable event bubbling.
EDIT 1: You're over-complicating things. Try this:
$(document).ready(function () {
$('.dropdown').toggle();
});
EDIT 2: Can you be more specific about what you want? If you want a particular element, when clicked, to control the motion of a particular list, try this:
$(document).ready(function () {
$('a.someLink').click(function() {
$('.dropdown').toggle();
});
});
Unfortunately none of the above answers were working for me. I found a solution shortly afterwards.
HTML
<li class="dropdown">
<a class="disablelink" href="#">Carbohydrates, proteins & fats</a>
<ul class="sub_navigation">
<li>Carbohydrates</li>
<li>Proteins</li>
<li>Fats</li>
</ul>
</li>
jquery script
$(document).ready(function() {
$('.dropdown').click(function() {
// When the event is triggered, grab the current element 'this' and
// find it's children '.sub_navigation' and display/hide them
$(this).find('.sub_navigation').slideToggle();
});
$(".disablelink").click(function(e) {
e.preventDefault();
});
});
That solution is working perfectly for me. I added in e.preventDefault(); to stop the page jumping up and down when i clicked on the link.