I am trying to toggle list based on if a link is hovered on.
Here is my jQuery
$(function(){
$('.lists li').hover(function(){
$('ul.list-display', this).toggle('slow');
});
});
Here is my HTML:
<ul class='lists'>
<li><a href='http://eloquentjavascript.net/2nd_edition/preview/01_values.html'>Values, Types, and Operators</a>
</li>
<li><a href='http://eloquentjavascript.net/2nd_edition/preview/02_program_structure.html'>Program Structure</a>
<ul class='list-display'>
<h6>Test Sections</h6>
<li>Test</li>
<li>Test</li>
</ul>
</li>
</ul>
The problem is, it toggles down whenever you hover over the li which spans fairly far across the page, so whenever you hover into that li, it fires the toggle function. Ideally I would like the hover to fire when the mouse is over the link with the ul, not over the whole area of the li.
I think I have to alter my first selector in my function but so far all of my attempts have failed.
I see that you used this to give a context to the ul, but that's why it didn't work when you changed it to trigger off the a. Instead, just traverse the DOM like this:
$('.lists li a').hover(function(){
$(this).parent().find('ul.list-display').toggle('slow');
});
$(function(){
$('.lists li a').hover(function(){
$('ul.list-display').toggle('slow');
}
);
});
This appears to be working
http://jsfiddle.net/z6LP5/
It is because your code is working for the list item. Not the hyperlink.
$(function(){
$('.lists li a').hover(function() { // reach the hyperlink
$('ul.list-display').toggle('slow');
}
);
Now this would execute when you hover over the hyperlink (a). And then it would toggle the unordered list with the className of list-display.
Related
I have this HTML code:
<ul class="menu">
<li>
li first generation element
<ul class="sub-menu">
<li>
li second generation element
</li>
</ul>
</li>
...More li's first generation elements with ul's inside
</ul>
And this JQuery event:
$(".menu > li").click(function(){
alert("click");
})
The problem that I am running into is that when I click on second generation li elements the event is being fired, this is because the first generation li element is being clicked too. This is causing that the event is fired in a wrong li element. I only want that this event fires when first generation of li elements are clicked.
How can I solve this?.
The second LI is inside the first LI.
Use:
e.stopPropagation()
OR
e.preventDefault();
stopPropagation Docs
I am trying to show which menu item is the active one when it's clicked on by reassigning a css class to the list item using jQuery. I've looked at some examples online and tried some different ones, but I can't seem to get mine to work at all. Can someone look at my code from my last try and tell me what I am doing wrong? Thanks for your help.
Script in HEAD tag:
<script type="text/javascript" src="script/jquery-1.11.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#topnavi ul li a").click(function () {
if ($(this).parent("li").hasClass(".select"))
$("#topnavi ul li a").parent("li").removeClass(".select").addClass(".norm");
$(this).parent("li").removeClass(".norm").addClass(".select");
});
});
</script>
HTML:
<div id="topnavi">
<ul>
<li class="select">HOME</li>
<li class="norm">ABOUT US</li>
<li class="norm">SERVICES</li>
<li class="norm">PACKAGES</li>
<li class="norm">COMMENTS</li>
<li class="norm">CONTACT US</li>
<asp:LoginView ID="lvBackgroundSound1" runat="server">
<RoleGroups>
<asp:RoleGroup Roles="administrator"><ContentTemplate><li class="norm">ADMIN</li></ContentTemplate></asp:RoleGroup>
</RoleGroups>
</asp:LoginView>
</ul>
</div>
When a new anchor in a list item is clicked on, I would like to assign the "norm" class to the list item surrounding the previously selected anchor and assign the "select" class to the list item surrounding the newly selected anchor.
You don't need the dot before the class name when using hasClass, addClass and removeClass.
Change
if ($(this).parent("li").hasClass(".select"))
$("#topnavi ul li a").parent("li").removeClass(".select").addClass(".norm");
$(this).parent("li").removeClass(".norm").addClass(".select");
to
if ($(this).parent("li").hasClass("select"))
$("#topnavi ul li a").parent("li").removeClass("select").addClass("norm");
$(this).parent("li").removeClass("norm").addClass("select");
In conjunction with Tobias' answer, you might want to add some opening brackets to this part of the code
if ($(this).parent("li").hasClass(".select")) {
$("#topnavi ul li a").parent("li").removeClass(".select").addClass(".norm");
$(this).parent("li").removeClass(".norm").addClass(".select");
}
Or something along those lines. You could also use .toggleClass() instead of removing and adding the classes.
Adding to what Tobias already mentioned, change
if ($(this).parent("li").hasClass(".select"))
$("#topnavi ul li a").parent("li").removeClass(".select").addClass(".norm");
$(this).parent("li").removeClass(".norm").addClass(".select");
To
$("#topnavi ul li").removeClass("select").addClass("norm");
$(this).parent("li").removeClass("norm").addClass("select");
This will make sure select class is assigned only to the selected li and rest other li elements will have norm class.
Friends, I am working on JavaScript for collapse/Expand <UL> list.
here is my Code. I am wanted to work on it, in Nth Level, i can show Child, but its not hiding Children.
I hope you guys will help me..
Thanks in Advance...
This will do the trick:
event.stopPropagation();
Docs.
If you debug your code you'll see that the event is being called for each parent ul. Check this out:
$("#ExpList ul li:has(ul)").click(function(event) {
event.stopPropagation();
$(this).find('> ul')
.toggleClass("hiddenChild")
.toggleClass("displayChild");
});
And the HTML:
<div id='ExpList'>
<ul>
<li>Platform-1
<ul class='hiddenChild'>
<li>Child-1
<ul class='hiddenChild'>
<li>P-C-C-1</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
Fiddle.
HTML considerations:
I don't know if you can use a div wrapping the whole list, but I think it would make more sense doing it;
You're using the id ExpList for all ul. This is not how we use an id. Instead, for selecting many elements use its own tag or a common class;
I removed the onClick = openChild() which were present in all ul. It was throwin an error in your fiddle.
JavaScript considerations:
You don't have to mix a selector with a find this way $("#ExpList").find('li:has(ul)'). You can just use it on the same selector, as I did $("#ExpList ul li:has(ul)");
You don't need to search for all ul children($(this).children('ul')) since you'll have just one, I used this instead, which looks for just one: $(this).find('> ul');
As said before, the event.stopPropagation() does the trick. You don't need to trigger click event on all parent ul.
In CSS, I just changed #ExpList to this #ExpList ul to work in the new structure. I hope it helps.
I'm working on a menu that is designed using an unordered list, with each list element containing a link to another page. However, I would also like to be able to click on each bullet point to open more subcategories that will also link to other pages.
Essentially, I would like to be able to click once on a link and have it go to the correct page, but I would also like to click on the bullet point and have it expand into the subcategories. I've been researching how to separate the bullet from the content of the li, but it doesn't seem to be working in my case, likely because my li contains a lot of subcategories. Here's an example:
<li id="m2l1" class="child">
Y
<ul id="u11">
<li class="gchild">Y.1</li>
<li class="gchild">Y.2</li>
<li class="gchild">Y.3</li>
<li class="gchild">Y.4</li>
<li class="gchild">Y.5</li>
<li class="gchild">Y.6</li>
<li class="gchild">Y.7</li>
<li class="gchild">Y.8</li>
<li class="gchild">Y.9</li>
</ul>
</li>
Does anyone have any suggestions as to how to separate the bullet from the text in my case?
Here's the link: http://jsfiddle.net/stamblerre/XYp48/17/
Thank you!!!
Your HTML is invalid. You can't have div inside your ul. Moreover, you can greatly simplify your code by moving separate logic for each li into one generic handler.
Something like this:
Demo: http://jsfiddle.net/abhitalks/XYp48/18/
CSS:
ul {
display: none;
overflow: hidden;
}
ul:first-child {
display: block;
}
JS:
$("li").on("click", function () {
$(this).children("ul").slideToggle();
return false;
});
Edit:
I deliberately left out checking of a because clicking the a would navigate to the respective pages (as mentioned in your question), so expand/collapse wouldn't matter.
However, as per your comment if you really want to remove a altogether from the handler, then you can use the event target to handle li without a. Something like this:
Demo 2: http://jsfiddle.net/abhitalks/XYp48/22/
JS:
$("li").on("click", function (e) {
var $t = $(e.target); // get the event target as a jQuery object
if (!$t.is('a')) { // check if the target is not an anchor
$(this).children("ul").slideToggle();
return false;
}
// otherwise if target is anchor, then do nothing
});
Change your list still to hide bullets, then modify your html to :
<li class="gchild">•Y.1</li>
Should do the trick.
<li class="gchild">Y.1</li>
One way that worked for me: remove the bullet with li { list-style-type: none; } then add your own bullets with the character • (alt-8 on a mac). Add that character inside a elements like so:
• X
with the label now outside of the element.
Hope this works for you!
Here's an example of what I'm aiming for:
I don't like I have to decorate a li element with a class in order to correctly fire the event. What happens if I have more than one nested category drop down? Things get messy quick!
I also can't seem to be able to select an option without it closing as soon as I leave the event capture area.
Any suggestions on how to build a well crafted, drop down navigation menu?
You don't really need any classes with some clever usage of the selectors :P
I set up a fiddle with an example, here's the code:
HTML:
<nav>
<ul>
<li>HOME</li>
<li>
OFFERS
<ul>
<li>
NEW
<ul>
<li>YAY!</li>
</ul>
</li>
</ul>
</li>
<li>SETTINGS</li>
<li>TV's</li>
<li>COMPUTERS</li>
<li>RICE</li>
</ul>
</nav>
As you see, not a single class/id was needed :P The element "OFFERS" is the only one with a drop-down menu, and inside that menu, the element "NEW" has another one.
CSS:
li > ul { display: none; }
li li { margin-left: 10px; }
The first style is the important one. At first, we want our submenus to be hidden. The other style is just for the sake of clarity.
jQuery:
$("nav ul li").hover(function(){
if ($("> ul", this).length > 0) {
$("> ul", this).show();
}
}, function(){
if ($("> ul", this).length > 0) {
$("> ul", this).hide();
}
});
Yup, as simple as that :) When we hover a menu element, we check if it has any ul direct children, if it does, we show them. When we leave the menu element, we check again if it has any ul direct children, and if it does, we hide them.
Of course, you'll need to style this up, and make sure your clear any float inside any li.
You would need to use classes to properly control the flow. Especially on your outer container.
For example in my menus i have a ul containing all the menu and each menu item is an li. Inside the li is the first level title, along with another ul containing the submenu.
<ul class="menu">
<li>
Item 1
<ul><!--Further items--></ul>
</li>
<li>
Item 2
<ul><!--Further items--></ul>
</li>
</ul>
You can then control this using child selectors. Although it is sometimes easier to simply use a class.
$(".menu > li") //First level items
$(".menu > li > ul") //Submenus
Say you wanted to make the menu slide down when you clicked on one of the first level items:
$(".menu > li").click(function() {
$this = $(this); //Caching. Not really needed for this example. But anyway :)
$this.children("ul").slideToggle("fast");
});
$(document).ready( function(){
$("ul.MenuNavi li").mouseover(function(){
$(this).children('ul').slideDown('3000');
});
$("ul.MenuNavi li").mouseleave(function(){
$(this).children('ul').stop(true).slideUp('3000');
});
});