Animated Drop Down Menu for a Template - javascript

I have never used jQuery before and I'm trying to do something really simple but it's been driving me crazy.
I have designed a template for a CMS and now I want to get its menus animated.
The picture below explains the structure of the menu (which is obviously generated by the CMS)
The code below is what I think should work, but it doesn't:
var menuItem = jQuery(".menu:first>li");
var subMenu;
for(var i=0; i<menuItem.length;i++)
{
var li = jQuery(menuItem[i]);
subMenu = li.children("ul");
if (subMenu.length)
li.hover(function(){ li.children("ul").slideToggle(250); });
}
Basically, what I'm doing is get the first level lis and then add a hover listener to them, telling them to animate their child ul (which is the actual sub menu).
What I get instead is when I point to "Products" it's own sub menu does not show, instead, the sub menu for "Contact Us" pops up! When I point to "Contact Us" its sub menu pops up like it is supposed to. Note: The brown ul is set to display:none
I appreciate any help.
Thank in advance
PS: I'm using jQuery 1.7.1 (if it matters)

It looks quite complicated for what your trying to achieve. i would do something like this.
$(".menu > li").hover(
//When mouse is over the menu button
function () {
$(this).children("ul").slideDown(250);
},
//When mouse leaves the menu / menu button
function () {
$(this).children("ul").slideUp(250);
}
);

I see what you're trying to do in your code but I think you should start with good jQuery practices first. It's really not hard, you'll see. And it will make your life a lot easier.
First of all, I'm not sure a loop is what you want here. jQuery offers a selector (which can be used with $ as a shortcut) to select classes and it's really powerful.
Build your menu like this (sort of):
<ul id="menu">
<li class="menu-item">Home
<ul>
<li></li>
<li></li>
</ul>
</li>
<li class="menu-item">Products
<ul>
<li></li>
<li></li>
</ul>
</li>
<li class="menu-item">Contact us
<ul>
<li></li>
<li></li>
</ul>
</li>
</ul>
Then you can select the menu items with
$('.menu-item')
and in its hover function, select the drop down with
$(this).childen('ul')
Then basically have fun!

Related

Open a sub-menu using jQuery

I have this menu:
What I want to do: when I click the image button on the right (#sub-menu) I want it to open the sub-menu (.sports2).
this is a sub-item html code for an example:
<a href="#"><li> Golf
<img src="strokesmenu.png" id="sub-menu" />
<ul class="sports2">
<li>British Open</li>
<li>Masters</li>
<li>PGA Championship</li>
<li>US Open</li>
</ul>
</li></a>
Why this code isn't working for me?
$('#sub-menu').click(function(){
//$('.sports2').slideToggle("slow");
$(this).find('ul>li').slideToggle(slow);
})
first of all, <li>British Open</li> this structuring is so wrong I cannot even describe it how wrong it is.
convert it to the <li>British Open</li> if you want to make click-able while li try using below css or similar to that
ul li a {
display: inline-block;
width:100%;
height:100%;
}
also there must be only one item with one id having multiple item is against the W3C rules and clicking the little icon is not so user friendly. so instead give class to main item li and hanle the click with that one.
$('li.main').click(function(){
$(this).find('ul').slideToggle('slow');
})
apparently you cannot do that so you have to bind it to the img first change id to the class e.g. class="sub-menu"
$('li img.sub-menu').click(function(){
//$(this) -> img .next() -> ul
$(this).next().slideToggle('slow');
})
now the $(this).find('ul>li').slideToggle('slow'); should work but it will open every li and might cause some problem issues.
instead I suggest using $(this).find('ul').slideToggle('slow'); so the list can be opened/closed. you see the animation differences by trying it and choose the best one for you.
EDIT FOR CLICK BUG:
well not sure if I get it right but as I understand in some cases you need to redirect the page in others open the sub menu.
in that case you can check if the li has submenu or not the following code should do the trick.
$('li.main').click(function(){
if ($(this).has("ul")) // if has submenu
$(this).find('ul>li').slideToggle('slow');
else
// your redirect code.
})

individually hiding drop-downs according to one child-jquery

So I've painfully got multiple drop-downs toggling states(hidden and shown) in JQuery but I have some code which tells the side bar which page is active and gives it the style active and I would like a drop down to not be hidden if there is a child active in it.
The top level link which you click to view the drop-down gets given the id "HAC"(has active child) if it has an active child but I think I might be burning my brain out on this.
Here's a jsfiddle page with the working demo of the problem.
the drop down is set out like this in a nav
<ul id="HAC" class='topLevel'>
<li class='subItem'>
<a class="active" href='thatpage.php'>That page</a>
</li>
<li class='subItem'>
<a href='thatotherpage.php'>That other page</a>
</li>
</ul>
thanks in advance for any help
I think what you are looking for is the jQuery :not selector. Here is an update to your fiddle
function dropDowns() {
//for each toplevel li a
$(".topLevel:not(#HAC) li a").each(function() {
//hide subitems if not HAC (has active children)
$(this).hide();
});
//Toggle show them on click
clickToggle();
}

li accordion style menu in one ul with multiple classes

I'm working on a website that uses ruby on rails to retrieve multiple links and place them into a single ul with multiple li elements of either class 'head' or class 'link'.
I am trying to get an accordion style effect working with this, so when a user clicks on a 'head' li the subsequent child 'link' li's appear and disappear when another 'head' li is clicked.
I know about the accordion in jquery ui but I dont think thats an option with the rails code being used in the project. I'm only an intern and I'm not sure if the CTO is going to spend his time redoing his code to suit me. I'm trying my best to work with what I've got.
Example of the code:
<ul>
<li class = "head">HEAD</li>
<li class = "link">link</li>
<li class = "link">link</li>
<li class = "link">link</li>
<li class = "head">HEAD</li>
<li class = "link">link</li>
<li class = "link">link</li>
<li class = "link">link</li>
<li class = "head">HEAD</li>
<li class = "link">link</li>
</ul>
<script>
$('li.link').hide();
$('li.head:first-child').click(function(){
$('li.link').slice(0, 3).slideToggle('slow');
});
</script>
This is the closest I've gotten so far for the desired effect.
I genuinely appreciate any help I get.
You really got it almost quite good, but you're just targeting the click on the first .head instead for all of them. Than, the .nextUntil() method will help you target the desired elements.
LIVE DEMO
$('li.link').hide();
$('li.head').click(function(){
$(this).nextUntil('.head').slideToggle('slow');
});
Docs:
http://api.jquery.com/nextuntil/
Further to Roko's answer, this might help with the accordion feature, collapsing any non-relevant links that are showing when a new Head is clicked on:
$('li.link').hide();
$('li.head').click(function(){
// gets all the previous links and hides them
$(this).prevAll('.link').slideUp('slow');
// gets all the links that come after the next head, and hides them too
var nextHead = $(this).nextAll('.head').first();
$(nextHead).nextAll('.link').slideUp('slow');
// toggles all the relevant links for the current head
$(this).nextUntil('.head').slideToggle('slow');
});
Demo here: http://jsfiddle.net/xwbrB/7/

jQuery: Finding and hiding single parent link in nested list menu within Div - using contains();

I have a site that's CMS has very limited menu control. As such I'm trying to work around these problems with jQuery to display the menu how I want. I know it will still be in the HTML but as long as it's displaying the way I want it will be fine (at least for my standards).
The menu in question currently looks something like this.
<div id="sidemenu">
<ul>
<li class="childlist">
GET RID OF THIS PARENT
<ul>
<li>Show this</li>
<li>Show this</li>
<li>Show this</li>
</ul>
</li>
</ul>
</div>
I have achieved what I want with the simple $('a:contains(GET RID OF THIS PARENT)').hide(); however the menu is being pulled into two locations and I only want to hide the one in the sidemenu div.
I have tried this approach:
$side = $('#sidemenu');
$hidethis = $('$side:contains('GET RID OF THIS PARENT')');
$hidethis.hide();
But this crashes the page (I've been playing around in the console in Chrome to try to get a solution)
I will be the first to admit my javascript is terrible so any assistance would be well received.
Thanks in advance.
Your code should look like...
$side = $('#sidemenu');
$hidethis = $side.find(':contains('GET RID OF THIS PARENT')');
$hidethis.hide();
try this:
jQuery("#slidemenu").find("a:contains('GIT RID OF THIS PARENT')").hide();
Find First instance...
jQuery("#slidemenu > .childlist:first").find("a:contains('GIT RID OF THIS PARENT')").hide();
Looping through all the children:
jQuery("#slidemenu").find(".childlist").each(function() {
var $childListBranch = jQuery(this);
$childListBranch.find("a:contains('GIT RID OF THIS PARENT')").hide();
});
You need to target what you want to hide. For instance if you want to hide a link which has "get rid of this parent" text you can target a:contains. If you want to hide its parent you need to target #sidemenu:contains to its parent. here is the code example
//Hide a link
$("a:contains('GET RID OF THIS PARENT')").hide();
//Hide its parent
$("#sidemenu:contains('GET RID OF THIS PARENT')").hide();
Jsfiddle Demo

Losing dropdown list info on mouseout

I have built a simple dropdown list which I populate with various links. It contains about 50 items, so I wrapped it in a div to make it scrollable. Problem is, when I mouseout, I lose the whole list, unless the first two list elelments are showing. I have constructed this dropdown as a submenu, with the first two links as the 'container' of sorts.
I somewhat understand why I am losing the entire list, but can't figure out how to make the top links reapear on mouseout.
$('.myMenu > li').bind('mouseover', openSubMenu);
function openSubMenu() {
$('.myMenu').css('overflow','auto');
$('.myMenu').css('height','400px');
$('.ulMenu').css('visibility', 'visible');
};
$('.myMenu > li').bind('mouseout', closeSubMenu);
function closeSubMenu() {
$('.myMenu').css('overflow','hidden');
$('.myMenu').css('height','20px');
$('.ulMenu').css('visibility', 'hidden');
}
}
</script>
<div id="menu">
<ul class="myMenu">
<li id="li_left"> Application </li>
<li id="li"> Hover For Listing
<ul id="tasksUl" class="ulMenu">
</ul>
</li>
</ul>
</div>
I think you also have to post your .css for the list. I think you got a menu and you wanna open a list on hovering <li id="li"> Hover For Listing
You are setting a
$('.myMenu').css('height','20px');
and I don't get why you would do that. Also your .css styles are pretty much deprecated.
Check the fiddle here: http://jsfiddle.net/eR2y9/1/
Works like a charm. There is no need for you to add a height for the menu because it's dynamically adjusting depending on the amount of entries inside. Also if set to display none it's not taking any space away.. If you have further questions or if I misunderstood your problem feel free to reply to my post and I will find a solution for ya.

Categories