I have a simple menu, and I want to do that when you click on the menu items to open a nested list. If you double-click then it must be opened and closed.
Html:
<ul class="menu">
<li class="has-child">Click here
<ul>
<li class="has-child">Click here
<ul>
<li>Level 3</li>
</ul>
</li>
<li>Level 2</li>
<li>Level 2</li>
</ul>
</li>
<li>Level 1</li>
<li>Level 1</li>
</ul>
jQuery:
$('li.has-child').on('click', function () {
var elem = $(this).children('ul');
if (elem.is(':hidden')) {
elem.slideDown(500);
} else {
elem.slideUp(500);
}
});
But when I click on a menu item in the second level, then the first is closed. Why is this happening and how to fix it?
[JSFiddle]
You need to stop the event from propagating from the parent to the child or vice-versa. You can use event.stopPropagation():
$('li.has-child').on('click', function (event) {
event.stopPropagation()
var elem = $(this).children('ul');
if (elem.is(':hidden')) {
elem.slideDown(500);
} else {
elem.slideUp(500);
}
});
you need to use stopPropagation
$(document).ready(function () {
$('li.has-child').on('click', function (event) {
event.stopPropagation();
var elem = $(this).children('ul');
if (elem.is(':hidden')) {
elem.slideDown(500);
} else {
elem.slideUp(500);
}
});
});
This then stops the click bubbling up to the parent li
Fiddle
Related
I have nested unordered list.
<ul id="catalogue">
<li>List
<ul>
<li>Item 1</li>
<li>Item 2
<ul>
<li>Item 1.1</li>
<li>Item 1.2
<ul>
<li>Item 1.2.1</li>
<li>Item 1.2.2
<ul>
<li>Item 1.2.2.1</li>
</ul>
</li>
<li>Item 1.2.3</li>
</ul>
</li>
<li>Item 1.3</li>
</ul>
</li>
<li>Item 3</li>
</ul>
</li>
</ul>
At the beginning only the very top level shows, but if you click on each LI, if there's a child UL in it, it should display the next lever, and so on. If you click on the same LI again, the level below should become hidden.
$(document).ready(function () {
$('#catalogue li').each(function () {
$(this).contents().first().wrap("<span/>")
});
$('#catalogue li > span').addClass('brd');
$('ul').hide();
$('#catalogue').show();
$('#catalogue li').click(function () {
var nxt = $(this).children('ul:first')
if ($(nxt).is(":visible")) {
$(nxt).slideUp();
} else {
$(nxt).slideDown();
}
$(this).parent().show();
});
});
If a user clicks on a sibling LI and it has a child UL, that UL should show but any sibling's ones should close.
You need to stop the event from propagating to the parent. Clicking on each li will invoke its own click handler and the event will propagate to its parent li invoke its handler and so on. So you can just stop it at one level by using event.stopPropagation(). And you can use slideToggle to toggle the current state of the element.
Try:
$('#tree li').click(function (e) {
e.stopPropagation();
$(this).children('ul:first').slideToggle();
});
Demo
And if you want to slide up while clicked on its sibling then,
$('#tree li').click(function (e) {
e.stopPropagation();
var $this = $(this);
$this.children('ul:first').slideToggle().end()
.siblings().children('ul:visible').slideUp();
//Code Broken down
//$this.children('ul:first').slideToggle();
//$this.siblings().children('ul:visible').slideUp();
});
Demo
I have a vertical menu with submenus and I want to show the submenu only if the parent was clicked ,showing only one submenu at a time. But the thing is when other parent menu is clicked its submenu is shown BUT the previous submenu also is seen. How do i hide the previous submenu?? please help . I am new to javascript.
Here is my html-css-javascript code.
<div class="menu">
<ul >
<li>Contacts
<div style="display: none;" id="cert">
<ul >
<li >Submenu 1</li>
<li>submenu 2</li>
</ul>
</div>
</li>
<li>About
<div style="display: none;" id="defect">
<ul >
<li>menu 1</li>
<li>menu 2</li>
</ul>
</div>
</li>
</ul>
script
function Myfunction(obj) {
var ele=document.getElementById(obj).style;
if(ele.display=="none") {
ele.display="block";
} else { ele.display="none"; }
}
The easiest way will be using a global JavaScript variable, although it's not very elegant. Since you're not using any JavaScript libraries like e.g. jQuery everything else will turn into a pile of DOM-traversing spaghetti code.
var openEle = null;
function Myfunction(obj) {
var ele = document.getElementById(obj);
if (openEle != null) {
openEle.style.display = "none");
}
if (ele.style.display == "none") {
openEle = ele;
ele.style.display = "block";
} else {
ele.style.display = "none";
}
}
<a class="Label">Contacts</a>
<div>
<ul class="Submenu">
<li>Menu 1</li>
<li>Menu 2</li>
</ul>
</div>
<a class="Label">About</a>
<div>
<ul class="Submenu">
<li>Menu 1</li>
<li>Menu 2</li>
</ul>
</div>
And :
(function($) {
$(function() {
$('.Label').on('click', function() {
$('.Submenu').hide();
$(this).next().find('.Submenu').show();
});
});
})(jQuery);
That's the jQuery approach. I'll let another couragous guy do it with native js :D
You can use this:
Demo here
var lastid;
function Myfunction(obj) {
var ele = document.getElementById(obj).style;
var elemLastId = document.getElementById(lastid);
if (elemLastId != null) {
elemLastId.style.display = "none";
}
lastid = obj;
if (ele.display == "none") {
ele.display = "block";
} else {
ele.display = "none";
}
}
I made a new variable to remember the last ID. So you can call it and apply display:none to it.
I have a one-page website with a menu like this:
<ul id="menu-menu" class="nav">
<li id="1">Item 1</li>
<li>Item 2
<ul>
<li id="1" class="sub">Item 2-1</li>
<li id="1" class="sub">Item 2-2</li>
<li id="1" class="sub">Item 2-3</li>
</ul>
</li>
<li id="1">Item 3</li>
<li id="1">Item 4</li>
</ul>
The menu is high-lighted by JavaScript:
<script type="text/javascript">
/* <![CDATA[ */
var J = jQuery.noConflict();
J(document).ready(function(){
J('.nav li:first').addClass('current');
J('ul.nav').each(function() {
J(this).find('li#1').each(function(i) {
J(this).click(function(){
J(this).addClass('current');
J(this).siblings().removeClass('current');
});
});
});
});
/* ]]> */
</script>
The problem is that when I click on Item 3 and than on Item 2-2, Item 3 stays high-lighted., and when I than click on Item 1, Item 2-2 stays high-lighted.
Any ideas how to fix this?
var J = jQuery.noConflict();
J(function(){
J('ul.nav li:first').addClass('current');
J('ul.nav li').click(function (e) {
J('ul.nav li.current').removeClass('current');
J(this).addClass('current');
e.stopPropagation(); // prevent the event click from bubbling up
});
});
Untested, but try to replace
J(this).addClass('current');
J(this).siblings().removeClass('current');
with
J('ul.nav .current').removeClass('current');
J(this).addClass('current');
.
The problem is that the sibling selector only finds just that, the siblings, and not the other elements.
The menu is supposed to show sub-items upon hover. Here's the code (from http://docs.jquery.com/Cookbook/Navigation):
<ul id="menu">
<li class="menu">Sub 1
<ul>
<li>test 1</li>
<li>test 2</li>
<li>test 3</li>
<li>test 4</li>
</ul>
</li>
<li class="menu">Sub 2
<ul>
<li>test 1</li>
<li>test 2</li>
<li>test 3</li>
<li>test 4</li>
</ul>
</li>
</ul>
jQuery code:
$(document).ready(function() {
var toggle = function(direction, display) {
return function() {
var self = this;
var ul = $("ul", this);
if( ul.css("display") == display && !self["block" + direction] ) {
self["block" + direction] = true;
ul["slide" + direction]("slow", function() {
self["block" + direction] = false;
});
}
};
}
$("li.menu").hover(toggle("Down", "none"), toggle("Up", "block"));
$("li.menu ul").hide();
});
What is this in the toggle function above? How is the code working? What is being selected by $("ul", this); ?
The "this" refers to the jQuery object $("li.menu") - when the hover method call applies the toggle function to that object. $("ul", this) selects ul elements that are children of the context provided in the second argument ("this"), thus it selects the ul elements nested within the li.menu elements. Hopefully that makes the hover/toggle functions make sense.
Is it possible to show and hide partially with jquery sliding functions?
Basically, there's a list with 7 items. But only the 1st two are showing initially, while the rest is hidden. I want that when the user clicks to view more, all 7 items should show. And when he/she clicks again only the 1st two are showing and the rest is hidden again. But I can't manage to do it. Please give me some light, thanks.
jquery:
var ul = $('ul'),
showMoreLnk = $('a.show-more');
$('a').click(function(e){
if(ul.outerHeight() === 38){
ul.find('li.hide').removeClass('hide').addClass('show');
ul.slideDown(function(){
showMoreLnk.text('Show less');
});
} else {
ul.slideUp(function(){
showMoreLnk.text('Show more');
ul.find('li.show').removeClass('show').addClass('hide');
});
}
e.preventDefault();
});
HTML:
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li class="hide">Item 3</li>
<li class="hide">Item 4</li>
<li class="hide">Item 5</li>
<li class="hide">Item 6</li>
<li class="hide">Item 7</li>
</ul>
show more
CSS:
.hide{
display: none;
}
.show{
display: block;
}
Try this:
$('a').click(function (e) {
e.preventDefault();
$('ul li.hide').slideToggle('slow');
});
Check this out.
http://sim.plified.com/2008/09/15/sliding-content-from-a-partial-height-with-jquery/
and the example:
http://sim.plified.com/jQuery/slide/#
Check out this code:
$('a.show-more').click(function (e) {
e.preventDefault();
var hidden_list = $('ul li.hide');
if (hidden_list.is(':hidden')) {
$(this).html("show less");
hidden_list.slideDown();
}
else {
$(this).html("show more");
hidden_list.slideUp();
}
});
I also created this for you to test in fiddle http://jsfiddle.net/Shanison/H4vbB/2/