click the same sub nav link to close the sub sub nav
click the main nav to close the sub nav
start over
this time when you go to click a sub nav to expose a sub sub nav it will open then close by itself.
why does it close by itself? it should stay open.
Here’s the js. it’s a little sloppy, I’ve been hammering away at this issue and changed code so many times:
$(function(){
$('a.sub').click(function(e){
e.preventDefault();
$(this).parent().toggleClass('showSub');
// this element is display:none; by default, attach event after made display:block; by toggleClass above
$('li.showSub > ul > li > a').click(function(e){
e.preventDefault();
// slide up all potentially open sub navs
//$('.showSubSub').slideUp();
// add a class for styles, and slide it down
//$(this).next().addClass('showSubSub').slideDown();
if ( $(this).next().is(":visible") ) {
$(this).next().slideUp();
}
if ( $(this).next().is(":hidden") ){
$(this).next().slideDown();
}
})
})
})
Well, the only thing I can come up with is since the code to control the sub nav sliding
// this element is display:none; by default, attach event after made display:block; by toggleClass above
$('li.showSub > ul > li > a').click(function(e){
e.preventDefault();
// slide up all potentially open sub navs
//$('.showSubSub').slideUp();
// add a class for styles, and slide it down
//$(this).next().addClass('showSubSub').slideDown();
if ( $(this).next().is(":visible") ) {
$(this).next().slideUp();
}
if ( $(this).next().is(":hidden") ){
$(this).next().slideDown();
}
})
is nested in side a main link, the event is being attached twice and throwing off the behavior i want.
The reason it’s nested is because the sub nav is display:none; by default and I was able to successfully attach an event to a display:none; element.
I think most of my issues with this will be solved if someone knows how i can attach events to an element that is display:none; by default.
Every time you open your main sub navigation you’re recreating the click event for it, see the below which will fix this.
$(function() {
$('a.sub').on('click', function(e) {
e.preventDefault();
$(this).parent().toggleClass('showSub');
});
// This element is hidden by default so we need to delegate a click event that watches for elements
// that have a class of "showSub"
$(document).on('click', '.showSub li > ul > li > a', function(e) {
e.preventDefault();
$(this).next().slideToggle();
});
});
It seems to work and allows for all elements to slide as required without having two different routines and works for the hidden elements. (I did add classes the the sub navs to identify them but could be done without the classes of course.).
I simply took his code and re-worked it into a delegated event, I noticed it was overdone but it been so warm here in Melbourne I just got it done as quick as possible :), as for your code the only thing I would change is the preventDefault line so it comes before the slide toggle otherwise if that fails the default action will take place.
Also drop down menu’s aren’t typically coded like this any more using classes and what not, from the trend I’ve seen going around data attributes are becoming a thing when it comes to managing DOM elements, of course this shouldn’t rule out classes all together but they are much easier to manage.
Ah ok thanks Chris that’s a good thing to remember:)
(Mind you if the slide failed then you may want the link to be actioned to allow navigation to a sub page as mentioned here..)
Also drop down menu’s aren’t typically coded like this any more using classes and what not, from the trend I’ve seen going around data attributes are becoming a thing when it comes to managing DOM elements, of course this shouldn’t rule out classes all together but they are much easier to manage.
Yes, I’ve seen data attributes used a lot (especially in bootstrap) but of course only valid in html5 (although I gather they will do no harm elsewhere).
I understand what that guy is getting at but not checking if for instance the variable my is not set is bad practice, allowing your code to fail on purpose is the wrong way to write an event as you have bound a custom action to it that should be carried out without any errors.
Chris was talking about data attributes. It removes the dependence from a class being present and less likelihood that an author would remove or change a class that the JS needs to work.