JSFiddle
http://jsfiddle.net/5rkrq4bw/strong text
JQuery Code
// Side Menu Starts
$('.SideNav .Menu a.MenuDrop').click(function(event){
event.preventDefault();
if(!$(this).hasClass('Active')) {
if(!$(this).parent().parent().hasClass('Active') && $(this).next().hasClass('sub-menu')) {
$(this).next().slideToggle();
$(this).addClass('Active');
} else {
$('.SideNav .Menu li ul').slideUp();
$(this).next().slideToggle();
$('.SideNav .Menu a.MenuDrop').removeClass('Active');
$(this).addClass('Active');
}
}
});
//Side Menu Ends
The Problem
Trying to integrate multiple tiers I am finding the problem of only being able to have one open at a time and checking to see if any others are open to close them.
What should happen
Demo
Category
Sub-Cat
Link
Link
Link
Sub-Cat
Link
Link
Link
Category
Sub-Cat
Link
Link
Link
Sub-Cat
Link
Link
Link
Explanation
Only one 'Category' to be expanded at a time
Only one 'Sub-Cat' inside to be expanded at a time
Adding / removing of 'Active' class.
Resolved: http://jsfiddle.net/wo4sj4pt/
JQuery Code:
(function(jQuery){
jQuery.fn.extend({
accordion: function() {
return this.each(function() {
var $ul = $(this);
if($ul.data('accordiated'))
return false;
$.each($ul.find('ul'), function(){
$(this).data('accordiated', true);
$(this).hide();
});
$.each($ul.find('a'), function(){
$(this).click(function(e){
activate(this);
return void(0);
});
});
var active = $('.Active');
if(active){
activate(active, 'toggle');
$(active).parents().show();
}
function activate(el,effect){
if (!effect) {
$(el)
.toggleClass('active')
.parent('li')
.siblings()
.find('a')
.removeClass('active')
.parent('li')
.children('ul, div')
.slideUp('fast');
}
$(el)
.siblings('ul, div')[(effect || 'slideToggle')]((!effect)?'fast':null);
}
});
}
});
})(jQuery);
Usage:
Link to JQuery and the above script
Make a multi-level list
Give your list a class/ID name such as '.SideNav'
Tell the script this is your accordion $('.SideNav').accordion();
http://jsfiddle.net/sabithpocker/5rkrq4bw/2/
$('.SideNav .Menu a.MenuDrop').click(function(event){
event.preventDefault();
console.log(this);
var subMenuToExpand = $('ul.sub-menu', $(this).parent());
var otherVisibleSubMenu = $('ul.sub-menu:visible', $(this).parents('.Menu'));
otherVisibleSubMenu.hide();
subMenuToExpand.show();
});
$('.SideNav .Menu a.MenuDrop').click(function(event){
$('ul.sub-menu:visible', $(this).parents('.Menu')).slideUp(50);
$('ul.sub-menu', $(this).parent()).slideDown();
});
Related
i have hamburger menu, which i've done an accordion type submenu using jquery. Though it's only for devices which are 1084px and smaller.
Otherwise the menu uses a hover style submenu on desktop.
Though for some reason, using both of these techniques (hover using css, and the accordion using jquery) is not working.
So i had resulted in adding media queries to the jquery, which had allowed the hover and accordion to work.
BUT
Once the accordion is pressed, it opens and closes multiple times by itself, which is wrong and therefore not functioning properly.
Can anyone help me out please, this problem only happens once i add the media query to my Jquery.
jQuery(document).ready(function($) {
$(window).resize(function() {
if ($(window).width() < 500) {
function initMenu() {
$('#nav ul').hide();
$('#nav li a').click(
function() {
var checkElement = $(this).next();
if ((checkElement.is('ul')) && (checkElement.is(':visible'))) {
$('#nav ul:visible').slideToggle('normal');
}
if ((checkElement.is('ul')) && (!checkElement.is(':visible'))) {
removeActiveClassFromAll();
$(this).addClass("active");
$('#nav ul:visible').slideToggle('normal');
checkElement.slideToggle('normal');
return false;
}
if ($(this).siblings('ul').length == 0 && $(this).parent().parent().attr('id') == 'nav') {
removeActiveClassFromAll();
$(this).addClass("active");
$('#nav ul:visible').slideToggle('normal');
return false;
}
}
);
}
function removeActiveClassFromAll() {
$('#nav li a').each(function(index) {
$(this).removeClass("active");
});
}
$(document).ready(function() {
initMenu();
});
$('#nav').click(function(e) {
e.stopPropagation();
})
$(document).click(function() {
$('#nav').children('li').each(function() {
if ($(this).children('ul').css('display') == 'block') {
$(this).children('ul').slideToggle('normal')
$(this).children('a').removeClass('active')
}
})
})
}
});
});
here is a jsfiddle https://jsfiddle.net/kjm58tah/
thank you in advance
if (window.matchMedia("(max-width: 500px)").matches) {
}
this will work, however you need to refresh the page to make it work..
my accordion is not working properly.
on the first time you click, the content is ont displaying . . . .
otherwise if you click the second time and after it does appear . .
Any help will be brilliant,
Here is my fiddle:
https://jsfiddle.net/ugddnof4/
All the thtml is there.
OR below is my js:
(function($) {
$('.accordion > li:eq(0) a').addClass('active').next().slideDown();
$('.accordion a').click(function(j) {
var dropDown = $(this).closest('li').find('ul.accordion-content li, p, ul.accordion-content');
$(this).closest('.accordion').find('ul.accordion-content li, p, ul.accordion-content').not(dropDown).slideUp();
if ($(this).hasClass('active')) {
$(this).removeClass('active');
} else {
$(this).closest('.accordion').find('a.active').removeClass('active');
$(this).addClass('active');
}
dropDown.stop(false, true).slideToggle();
j.preventDefault();
});
})(jQuery);
thanks a lot for all your time!
This seems to work
https://jsfiddle.net/9erfLokh/1/
New js:
(function($) {
$('.accordion > li:eq(0) a').addClass('active').next().slideDown();
$('.accordion a').click(function(j) {
var dropDown = $(this).closest('li').find('ul.accordion-content');
if ($(this).hasClass('active')) {
$(this).removeClass('active');
} else {
$(this).closest('.accordion').find('a.active').closest('li').find('ul.accordion-content').slideUp();
$(this).closest('.accordion').find('a.active').removeClass('active');
$(this).addClass('active');
}
dropDown.stop(false, true).slideToggle();
j.preventDefault();
});
})(jQuery);
I think your problem was mainly that dropDown was returning a whole set of dom objects, and you were running slideToggle on all of them. This version will only close a block if there is one active, and will always toggle the clicked one, but takes care to only run slideToggle on a single element.
I have been working on navigation bar and the strangest issue is occurring.
Please use the JSFiddle link to see what I mean.
To duplicate the error:
Run the code when the desktop view is active i.e. when the navigation links are in a line.
Then resize the screen till the "click me" is displayed.
Then press it.
Now run the code while you see the "click me" and press it again.
JS information
jQuery(document).ready(function($) {
// UserCP
$('.rotate').on('click', function() {
$(this).toggleClass("down");
});
$('.nav-start').on('click', function() {
$("#nav2").removeClass("hidden");
$('#nav2 li a').stop().slideToggle('100');
return false;
});
$(document).ready(function() {
$('#nav2 li a').stop().slideToggle('100');
});
$('body').on('click', function() {
$('#nav2 li a').stop().slideUp('100');
});
$("#nav2 li a").click(function(e) {
e.stopPropagation();
});
$(document).click(function(event) {
if (!$(event.target).closest('#nav2 li a').length) {
if ($('#nav2 li a').is(":visible")) {
$('html, body').on('click', function() {
$('#nav2 li a').stop().slideUp('100');
});
};
};
});
});
FIXED - UPDATED JSFiddle! Thanks #Louys Patrice Bessette #Titus #Rick
You are using two click events on this "Click me" li...
(One on .navstart and one on .rotate)
It may not be an issue, but this make the code harder to read.
Then, when you slideToggle(), if you want the submenu to slide down, it has to be hidden.
Because, since you remove the hidden class (probably usefull on load), the submenu is visible.
A Toggle hides it.
I simplified your script to this.
Have a look at this updated Fiddle.
$(document).ready(function() {
// Show submenu on "Click me"
$('.nav-start').on('click', function() {
$('.rotate').toggleClass("down");
$("#nav2").removeClass("hidden");
var subNav = $('#nav2 li a');
if(subNav.css("display")=="block"){
subNav.stop().slideUp('100');
}else{
subNav.stop().slideDown('100');
}
return false;
});
$("#nav2 li a").click(function(e) {
e.stopPropagation();
});
// Hide submenu on document click
$(document).click(function(event) {
if (!$(event.target).closest('#nav2 li a').length && $('#nav2 li a').is(":visible")) {
$('#nav2 li a').stop().slideUp('100');
};
});
});
JQuery Accordion
(function(jQuery){
jQuery.fn.extend({
accordion: function() {
return this.each(function() {
var $ul = $(this);
if($ul.data('accordiated'))
return false;
$.each($ul.find('ul'), function(){
$(this).data('accordiated', true);
$(this).hide();
});
$.each($ul.find('a'), function(){
$(this).click(function(e){
//if(!$(this).hasClass('Active')) {
activate(this);
return void(0);
//}
});
});
var active = $('.Active');
if(active){
activate(active, 'toggle');
$(active).parents().show();
}
function activate(el,effect){
if (!effect) {
$(el)
.toggleClass('Active')
.parent('li')
.siblings()
.find('a')
.removeClass('Active')
.parent('li')
.children('ul')
.slideUp('fast');
}
$(el)
.siblings('ul')[(effect || 'slideToggle')]((!effect)?'fast':null);
}
});
}
});
})(jQuery);
Calling Accordion
$('.Menu.Open').accordion();
The Problem
.Menu.Open is inside of .SideNav of which I want to get the new height after my accordion has collapsed/expanded content to set the height of .Main
I've been looking into timers and timed events however I just cannot get this to work after my accordion has expanded and feel my attempts are completely wrong, I'd hate to flood this page with them all!
Looking at your code, you are relying on Jquery.slideUp/slideDown to expand/collapse your accordion. If I understood you correctly you are trying to measure height after the animation is complete. I believe this is what you are looking for
$('element').slideUp('fast', function(){ perform_measurement_here();});
Also, for your reference
http://api.jquery.com/slideup/
I have this jQuery code that opens an accordeon on hover but i need to make it work each tab on click instead, i've tried to change the "hover" to "click" but no success, could someone here please help me ?
Thanks in advance.
$(function() {
$('#accordion > li').hover(function() {
var $this = $(this);
$this.stop().animate({'width':'480px'},500);
$('.heading',$this).stop(true,true).fadeOut();
$('.bgDescription',$this).stop(true,true).slideDown(500);
$('.description',$this).stop(true,true).fadeIn();
}, function() {
var $this = $(this);
$this.stop().animate({'width':'115px'},1000);
$('.heading',$this).stop(true,true).fadeIn();
$('.description',$this).stop(true,true).fadeOut(500);
$('.bgDescription',$this).stop(true,true).slideUp(700);
});
});
the idea from Tushar Gupta is the only one that's partially working, it opens the accordeon on click, but if the user clicks another tab while one is open there's a bug...
i make a fiddle with the whole code.
http://jsfiddle.net/C8Kp8/ <-- Tushar Gupta's solution
http://jsfiddle.net/SHmuc/ <-- Original Code
thank you all for your help, its really appreciated.
You can use .toggle() or this
$(function() {
$('#accordion > li').click(function() {
var $this = $(this);
if ($this.hasClass('open')) {
$this.stop().animate({'width':'480px'},500);
$('.heading',$this).stop(true,true).fadeOut();
$('.bgDescription',$this).stop(true,true).slideDown(500);
$('.description',$this).stop(true,true).fadeIn();
$this.removeClass('open');
}
else {
$this.stop().animate({'width':'115px'},1000);
$('.heading',$this).stop(true,true).fadeIn();
$('.description',$this).stop(true,true).fadeOut(500);
$('.bgDescription',$this).stop(true,true).slideUp(700);
$this.addClass('open');
}
});
});
Take a look at this. #Alex's answer is good but ignores the first click, and doesn't close the open elements when a closed element is clicked. FIDDLE. In this version, the more links in the accordion elements also work.
$(function() {
$('#accordion li').click(function() {
var $this = $(this);
if (!$this.hasClass('open')) {
// open clicked accordion element
$this.stop().animate({'width':'480px'},500);
$('.heading',$this).stop(true,true).fadeOut();
$('.bgDescription',$this).stop(true,true).slideDown(500);
$('.description',$this).stop(true,true).fadeIn();
// close other open accordion element
$("#accordion li.open").stop().animate({'width':'115px'},1000);
$("#accordion li.open .heading").stop(true, true).fadeIn();
$("#accordion li.open .description, #accordion li.open .bgDescription").stop(true, true).fadeOut();
$("#accordion li.open").removeClass("open");
$this.addClass('open');
}
else {
// close this accordion element
$this.stop().animate({'width':'115px'},1000);
$('.heading',$this).stop(true,true).fadeIn();
$('.description',$this).stop(true,true).fadeOut(500);
$('.bgDescription',$this).stop(true,true).slideUp(700);
$this.removeClass('open');
}
});
$('#accordion > li a').click(function(e){
e.stopPropagation();
});
});