hello everybody I have a list like this <ul id="main_menu"> <li><a href="#">Comments</a></li> <li><a href="#">[COLOR=#000000]Advertising[/COLOR]</a> <ul> <li><a href="#">edit/delete ads</a></li> <li><a href="#">Add Ads</a></li> </ul> </li> <li><a href="#">Groups</a></li> <li><a href="#">Members</a> <ul> <li><a href="#">Edit / Delete Member</a></li> <li><a href="#">Add Member</a></li> </ul> </li> <li><a href="#">Photo</a> <ul> <li><a href="#">edit / Delete Photo</a></li> <li><a href="#">Add a picture</a></li> </ul> </li> <li><a href="#">Sections</a> <ul> <li><a href="#">Edit / Delete section</a></li> <li><a href="#">Add Section</a></li> </ul> </li> <li><a href="#">General Settings</a></li> <li><a href="#">Home</a></li> </ul> Code (markup): This list contains lists of 8, including 4 lists contain children (Advertising,Members,Photo,Sections) And I've written this code but did not work very well function MainMenu(item){ var MenuItems = document.getElementById('main_menu'); for (var i = 0; i < MenuItems.children.length; i++) { MenuItems.children[i].children[1].style.display = "none"; } item.children[1].style.display = "block"; } Code (markup): What i needed is when i press a list containing the submenus Close all open lists Then open this menu
You need to use 'onclick' event attribute in your hyperlinks to run that function of yours once you click it. eg: <a href="#" [B]onclick='whatever( );'[/B]>Comments</a></li> Code (markup): See: http://www.w3schools.com/TAGS/tag_a.asp
Thanks Rainulf for your Help but I know this code But I forgot to write in the example at the top But this is not the solution
You're not making sure that the lis actually have 2 children (an a and an ul) and in some cases, like your comments or home lis, they don't. This throws and error and stops your code working. Adding a quick check solves the problem. function MainMenu(item) { var MenuItems = document.getElementById('main_menu'); for (var i = 0; i < MenuItems.children.length; i++) { if (MenuItems.children[i].childElementCount > 1) MenuItems.children[i].children[1].style.display = "none"; } if (item.childElementCount > 1) item.children[1].style.display = "block"; } Code (markup):
Thanks meloncholy Indeed, this is the right solution to the problem, But unfortunately, this code does not work on Internet Explorer I think the Internet Explorer browser does not support the function (childElementCount)
Oops. My bad. I didn't check and apparently it's not widely supported. The link says children.length is a better alternative. Though personally I'd have avoided it all with a line or two of jQuery. $("#main_menu>li ul").hide(); $(this).children("ul").show(); Code (markup): $(this).children("ul").show().parent().siblings().children("ul").hide(); Code (markup):
Thank you for your continue help me But I wish it were JavaScript code not Jquery any way thank you for your help
Probably this function shall do: function MainMenu(item){ var aChild = document.getElementById('main_menu').getElementsByTagName('ul'); for (var i = 0; i < aChild.length; i++) { aChild[i].style.display = (aChild[i].parentNode == item.parentNode)? "block" : "none"; } } HTML: and the link should look like: <li><a href="javascript:void(0)" onclick="MainMenu(this)">Advertising</a> HTML: Though I'm not sure IE would support .parentNode ?
can this be done using just javascript and not using jquery ? of course it can. it took me a little while to come up with the solution, but this is it. the children uls (under: Advertising, Members, Photo, and Sections) each get a unique ID ( i used 'a1', 'a2' etc) the main list items without children get a function to close all the uls. the main list items with children (Advertising, Members, Photo, and Sections) get a function which passes the ID of the ul . the function then just first closes all the ul, and then opens the correct one. here is the correct code to make it work. it will need some extra work to make it pretty, though. and i agree, jquery or another framework would make it more 'elegant'. but none-the -less, for learning purposes, i offer this up ,and it should work across all browsers: <html> <head> <script type="text/javascript"> function closeLists() { for (var i=0;i<8;i++) {document.getElementById("main_menu").getElementsByTagName("ul")[i].style.display="none"}; } function closeLists2(q) { for (var x=0;x<4;x++) {document.getElementById("main_menu").getElementsByTagName("ul")[x].style.display="none"; document.getElementById(q).style.display="block"; } } </script> </head> <body id="body"> <ul id="main_menu"> <li onclick="closeLists()">Comments</li> <li onclick="closeLists2('a1')"><a href="#">Advertising</a> <ul id="a1"> <li><a href="#">edit/delete ads</a></li> <li><a href="#">Add Ads</a></li> </ul> </li> <li onclick="closeLists()"><a href="#">Groups</a></li> <li onclick="closeLists2('a2')"><a href="#">Members</a> <ul id="a2"> <li><a href="#">Edit / Delete Member</a></li> <li><a href="#">Add Member</a></li> </ul> </li> <li onclick="closeLists2('a3')"><a href="#">Photo</a> <ul id="a3"> <li><a href="#">edit / Delete Photo</a></li> <li><a href="#">Add a picture</a></li> </ul> </li> <li onclick="closeLists2('a4')"><a href="#">Sections</a> <ul id="a4"> <li><a href="#">Edit / Delete section</a></li> <li><a href="#">Add Section</a></li> </ul> </li> <li onclick="closeLists()"><a href="#">General Settings</a></li> <li onclick="closeLists()"><a href="#">Home</a></li> </ul> </body> </html> Code (markup):
Whoa! I'm sure lionking is very grateful for all of the help, but I imagine 3 solutions to his problem (plus 2 in jQuery) is probably enough.
hi meloncholy - can you please elaborate on your response? i am not sure what point you were trying to make. are you suggesting to NOT offer solutions and help? especially when it is clear that lionking has NOT had his question answered fully before ( i.e. to NOT have to use jquery, AND to not use something unsupported in IE ). i would like to think that we are all sharing our knowledge and enthusiasm in a friendly and free manner.....
Hey tdemetri, I'm sorry if my reply came across in the wrong way. I didn't mean it to be taken too seriously, and certainly wasn't intended as criticism of anyone posting here. The solution I provided works fine in IE if childElementCount is swapped for children.length, as I mentioned in my earlier reply. Then hdewantara posted another solution (which admittedly I haven't tried), followed shortly by your solution. That makes 3, plus the jQuery ones I listed. And, well, 3 answers seemed like it was probably sufficient for now. But I do think it's great that people are being so helpful here, and that this is an active and positive forum. It's a great place to get help and a great place to help out too, which of course is mostly down to people like those posting in this thread.
no problem meloncholy, - still friends - and i didn't see where you said: BUT - in trying out your code, i do see how it will close all the ULs, but i don't see how it will open the child of the parent which was clicked. i would be grateful if you could explain that, and/or post a working sample
Phew. Sure. I only added a couple of bits to lionking's original code, so this part is really his solution. The line in question is if (item.children.length > 1) item.children[1].style.display = "block"; Code (markup): The clicked li is passed into the function as item, so after iterating through and hiding all of the menus, the clicked li's second child (the ul) is made visible. In my test code I've cheated and used jQuery to bind the click event to the lis, but you could do it by adding onclick="MainMenu(this);" to the comments, advertising, etc. lis or through another method too of course. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>Untitled Page</title> <script type="text/javascript" src="jquery/jquery-1.4.2.js"></script> <script type="text/javascript"> function MainMenu(item) { var MenuItems = document.getElementById('main_menu'); for (var i = 0; i < MenuItems.children.length; i++) { if (MenuItems.children[i].children.length > 1) MenuItems.children[i].children[1].style.display = "none"; } if (item.children.length > 1) item.children[1].style.display = "block"; } (function ($) { $(document).ready(function () { $("#main_menu>li").click(function() { MainMenu(this); }); }); })(jQuery); </script> </head> <body> <ul id="main_menu"> <li><a href="#">Comments</a></li> <li><a href="#">Advertising</a> <ul> <li><a href="#">edit/delete ads</a></li> <li><a href="#">Add Ads</a></li> </ul> </li> <li><a href="#">Groups</a></li> <li><a href="#">Members</a> <ul> <li><a href="#">Edit / Delete Member</a></li> <li><a href="#">Add Member</a></li> </ul> </li> <li><a href="#">Photo</a> <ul> <li><a href="#">edit / Delete Photo</a></li> <li><a href="#">Add a picture</a></li> </ul> </li> <li><a href="#">Sections</a> <ul> <li><a href="#">Edit / Delete section</a></li> <li><a href="#">Add Section</a></li> </ul> </li> <li><a href="#">General Settings</a></li> <li><a href="#">Home</a></li> </ul> </body> </html> HTML:
so he he he.... all kidding aside, i don't see it working like that, and i've tested and re-tested . here is a posted example using my (non jquery) code: demetri-media.com/JavaScript/XHTMLtest3.html if you could post an example using your code i would be grateful, as i'd love to compare it and see where i am going wrong in trying to do it with jquery. you friend, -demetri-
Hmmm... I'm not sure what's going wrong for you. Let me try again. Here's the code with no jQuery and with the onclick events added. (All the jQuery was doing was saving me from adding the onclicks manually.) <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>Untitled Page</title> <script type="text/javascript"> function MainMenu(item) { var MenuItems = document.getElementById('main_menu'); for (var i = 0; i < MenuItems.children.length; i++) { if (MenuItems.children[i].children.length > 1) MenuItems.children[i].children[1].style.display = "none"; } if (item.children.length > 1) item.children[1].style.display = "block"; } </script> </head> <body> <ul id="main_menu"> <li onclick="MainMenu(this);"><a href="#">Comments</a></li> <li onclick="MainMenu(this);"><a href="#">Advertising</a> <ul> <li><a href="#">edit/delete ads</a></li> <li><a href="#">Add Ads</a></li> </ul> </li> <li onclick="MainMenu(this);"><a href="#">Groups</a></li> <li onclick="MainMenu(this);"><a href="#">Members</a> <ul> <li><a href="#">Edit / Delete Member</a></li> <li><a href="#">Add Member</a></li> </ul> </li> <li onclick="MainMenu(this);"><a href="#">Photo</a> <ul> <li><a href="#">edit / Delete Photo</a></li> <li><a href="#">Add a picture</a></li> </ul> </li> <li onclick="MainMenu(this);"><a href="#">Sections</a> <ul> <li><a href="#">Edit / Delete section</a></li> <li><a href="#">Add Section</a></li> </ul> </li> <li onclick="MainMenu(this);"><a href="#">General Settings</a></li> <li onclick="MainMenu(this);"><a href="#">Home</a></li> </ul> </body> </html> HTML: And, if you prefer, here's a link to the same code on a page. Works for me...