24 replies [Last post]
thepineapplehead
thepineapplehead's picture
Offline
Guru
Last seen: 4 weeks 7 hours ago
Timezone: GMT+1
Joined: 2004-06-30
Posts: 9674
Points: 810

Hopefully a simple one some of the JS Gurus can help me with.

I want to create a menu, with submenus. I want the submenus to show/hide when the menu heading is clicked.

I've found numerous bulky JS examples, but I'm sure there's an easier way.

Something like giving the sub-menu ul a class, and giving this class display:none. Then, using onclick, giving it a style of display:block.

Even some simple pointers about using JS to change styles would be great, I'm willing to learn!

Verschwindende wrote:
  • CSS doesn't make pies

Tags:
gary.turner
gary.turner's picture
Offline
Moderator
Dallas
Last seen: 33 weeks 3 days ago
Dallas
Timezone: GMT-6
Joined: 2004-06-25
Posts: 9776
Points: 3858

JS Show/Hide menu

I discuss some issues with showing and hiding elements (divs in this case) in this demo.

You might also take a look-see at this demo for a variation.

You should be able to adapt something from these to your purpose.

cheers,

gary

If your web page is as clever as you can make it, it's probably too clever for you to debug or maintain.

thepineapplehead
thepineapplehead's picture
Offline
Guru
Last seen: 4 weeks 7 hours ago
Timezone: GMT+1
Joined: 2004-06-30
Posts: 9674
Points: 810

JS Show/Hide menu

Brilliant, that looks just what I'm after. Thanks Gary.

As an aside; on the flipflop divs, could you use the whatever.hover file to change the cursor on hover? or is it not worth the extra code?

Verschwindende wrote:
  • CSS doesn't make pies

gary.turner
gary.turner's picture
Offline
Moderator
Dallas
Last seen: 33 weeks 3 days ago
Dallas
Timezone: GMT-6
Joined: 2004-06-25
Posts: 9776
Points: 3858

JS Show/Hide menu

You're welcome.

Yeah, you probably could. I didn't in the demo, and probably wouldn't bother[1] in the real world unless it affected usability or accessibility. If it's just incremental experience enhancement, i.e. bells and whistles, I tend to say sca-rew IE.

cheers,

gary

[1] More than likely I would use some work-around other than scripting, for accessibility reasons.

If your web page is as clever as you can make it, it's probably too clever for you to debug or maintain.

Tyssen
Tyssen's picture
Offline
Moderator
Brisbane
Last seen: 7 years 1 week ago
Brisbane
Timezone: GMT+10
Joined: 2004-05-01
Posts: 8201
Points: 1386

JS Show/Hide menu

I found a good, reasonably lightweight example a little while ago that I used on a site I did. The article's been updated since: http://www.gazingus.org/html/DOM-Scripted_Lists_Revisited.html

How to get help
Post a link. If you can't post a link, jsFiddle it.
My blog | My older articles | CSS Reference

thepineapplehead
thepineapplehead's picture
Offline
Guru
Last seen: 4 weeks 7 hours ago
Timezone: GMT+1
Joined: 2004-06-30
Posts: 9674
Points: 810

JS Show/Hide menu

Tysse, that's brilliant.

There's just one thing I don't like; if you click the link text (instead of the + sign), the hash takes you to the top of the page.

Isn't there a JS command that leaves it as an empty link but doesn't take you to the top of the page?

Verschwindende wrote:
  • CSS doesn't make pies

HellsBells
HellsBells's picture
Offline
Leader
Bedford, UK
Last seen: 13 years 25 weeks ago
Bedford, UK
Joined: 2004-04-07
Posts: 851
Points: 0

JS Show/Hide menu

Hi TPH

There's a few here too just in case you need any more!

http://www.bobbyvandersluis.com/articles/unobtrusiveshowhide.php

Unlike some of the JS ones I've seen in the past - if JS is disabled it'll show all items automatically.

My strategy is so simple an idiot could have devised it!

"Also, your CSS (no offence) makes me want to gouge my eyes out with a rusty spoon" - TPH

thepineapplehead
thepineapplehead's picture
Offline
Guru
Last seen: 4 weeks 7 hours ago
Timezone: GMT+1
Joined: 2004-06-30
Posts: 9674
Points: 810

JS Show/Hide menu

<bump>

I thought I understood it . . . but I can't get my head around any of it!

<ul>
<li id="nav-home"> <a href="index.html" title="The Foundation">Home</a> </li>
<li id="nav-training"> <a href="training.html" title="Training">Training</a>
  <ul id="nav-training-sub">
    <li> <a href="training.html#E2E" title="E2E">E2E</a> </li>
    <li> <a href="training.html#ET" title="ET">ET</a> </li>
    <li> <a href="training.html#newdeal" title="New Deal">New Deal</a> </li>
  </ul>
</li>
<li id="nav-housing"> <a href="housing.html" title="Housing">Housing</a> </li>
<li id="nav-outreach"> <a href="outreach.html" title="Outreach">Outreach</a> </li>
<li id="nav-env"> <a href="environment.html" title="Environment">Environment</a> </li>
<li id="nav-credit"><a href="credit.html" title="Credit Union">Credit Union</a> </li>
<li id="nav-info"> <a href="foundationhouse.html" title="Foundation House">Foundation House</a> </li>
<li id="nav-eat"> <a href="eatingpoint.html" title="Eating Point">Eating Point</a> </li>
<li id="nav-review"> <a href="annualreview.html" title="Annual Review">Annual Review</a> </li>
<li id="nav-vacancy"> <a href="vacancies.html" title="Staff Vacancies">Staff Vacancies </a> </li>
<li id="nav-contact"> <a href="contact.html" title="Contact Details"> Contact Details </a> </li>
</ul>

That's my code . . . little help?

Verschwindende wrote:
  • CSS doesn't make pies

HellsBells
HellsBells's picture
Offline
Leader
Bedford, UK
Last seen: 13 years 25 weeks ago
Bedford, UK
Joined: 2004-04-07
Posts: 851
Points: 0

JS Show/Hide menu

Which method are you going for the List Method or the Hiding Divs method?

Edit: (*slaps head*) sorry obviously you're going for the expanding list method. The gazingus.org technique just seems to need the ul to have the class "expandable" plus the JS to work. What problems are you having?

My strategy is so simple an idiot could have devised it!

"Also, your CSS (no offence) makes me want to gouge my eyes out with a rusty spoon" - TPH

thepineapplehead
thepineapplehead's picture
Offline
Guru
Last seen: 4 weeks 7 hours ago
Timezone: GMT+1
Joined: 2004-06-30
Posts: 9674
Points: 810

JS Show/Hide menu

This:

http://geocities.com/magicboy2000uk/mkcf/

nothing shows up in FF, and in IE I get a JS warning.

I do have some CSS rules and another bit of JS in there; I'll have a tweak and see what I can get.

/edit

Doh, I had about a million typos in there.

http://geocities.com/magicboy2000uk/mkcf/index_jsmenu.html

This is the new page; am I doing anything wrong?

Verschwindende wrote:
  • CSS doesn't make pies

HellsBells
HellsBells's picture
Offline
Leader
Bedford, UK
Last seen: 13 years 25 weeks ago
Bedford, UK
Joined: 2004-04-07
Posts: 851
Points: 0

JS Show/Hide menu

You've missed a closing " on the expandable class on the UL and a closing " on the <script tpye="text/javascript language="javascript> - not sure what that'd do to it but...

My strategy is so simple an idiot could have devised it!

"Also, your CSS (no offence) makes me want to gouge my eyes out with a rusty spoon" - TPH

thepineapplehead
thepineapplehead's picture
Offline
Guru
Last seen: 4 weeks 7 hours ago
Timezone: GMT+1
Joined: 2004-06-30
Posts: 9674
Points: 810

JS Show/Hide menu

<teh refresh>

new page (my edit), I fixed the errors, but no dice.

Verschwindende wrote:
  • CSS doesn't make pies

Chris..S
Chris..S's picture
Offline
Moderator
Last seen: 9 years 4 weeks ago
Timezone: GMT+1
Joined: 2005-02-22
Posts: 6078
Points: 173

JS Show/Hide menu

The submenu shows up for me in FF - there is a huge amount of screen flicker though.

When I view source on the page there are some wierd characters in the replace line of your script.

  this.className=this.className.replace�
	(" over", "");

thepineapplehead
thepineapplehead's picture
Offline
Guru
Last seen: 4 weeks 7 hours ago
Timezone: GMT+1
Joined: 2004-06-30
Posts: 9674
Points: 810

JS Show/Hide menu

I'll have a look into that; however I can see the submenu fine, but it shoudl be hidden.

Verschwindende wrote:
  • CSS doesn't make pies

HellsBells
HellsBells's picture
Offline
Leader
Bedford, UK
Last seen: 13 years 25 weeks ago
Bedford, UK
Joined: 2004-04-07
Posts: 851
Points: 0

JS Show/Hide menu

OK got it I think.

In the sub menu ul you've got class="expandable" get rid of that (you only need it on the top level one) and substitute style="display:none;" and that seems to work.

In both your example and the original I was getting the submenu displayed by default rather than retracted by default. Putting in the display none sorts that out.

My strategy is so simple an idiot could have devised it!

"Also, your CSS (no offence) makes me want to gouge my eyes out with a rusty spoon" - TPH

thepineapplehead
thepineapplehead's picture
Offline
Guru
Last seen: 4 weeks 7 hours ago
Timezone: GMT+1
Joined: 2004-06-30
Posts: 9674
Points: 810

JS Show/Hide menu

http://geocities.com/magicboy2000uk/mkcf/index_jsmenu.html

The display:none hides it, but I can't seem to make it expand . . .

Verschwindende wrote:
  • CSS doesn't make pies

HellsBells
HellsBells's picture
Offline
Leader
Bedford, UK
Last seen: 13 years 25 weeks ago
Bedford, UK
Joined: 2004-04-07
Posts: 851
Points: 0

JS Show/Hide menu

I was taking bits of the page out to see what helped/hindered. I took out the body onload stuff just leaving the body and id and it works fine locally for me.

Here's what I used:

<!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" lang="en" xml:lang="en">

<head>
<script src="expandable.js" type="text/javascript"></script>
<title>Welcome to Milton Keynes Christian Foundation</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta name="keywords" content="christian, foundation, milton keynes, young people,foyer, training,it, environmental" />
<link rel="stylesheet" type="text/css" href="layout_jsmenu.css" />
<script language="JavaScript" type="text/JavaScript" src="scripts.js"></script> 
</head>

<body id="home">


<div id="holder" class="cutout"> <!-- Holds all content, also has the 'cutout.gif' background in top right -->

<div id="topbar"> <!-- Simply holds the mouseover images -->
<a href="Foundation.html" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('Image8','','IMAGES/build.jpg',1)"><img src="IMAGES/animal.jpg" name="Image8" width="125" height="75" border="0"></a>
<a href="Extended%20Training.html" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('Image7','','IMAGES/twowomen.jpg',1)"><img src="IMAGES/two.jpg" name="Image7" width="186" height="75" border="0"></a>
<a href="Environment.html" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('Image5','','IMAGES/digA.jpg',1)"><img src="IMAGES/pool.jpg" name="Image5" width="125" height="74" border="0"></a>
<a href="Foyer.html" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('Image6','','IMAGES/foy.jpg',1)"><img src="IMAGES/COok.jpg" name="Image6" width="70" height="75" border="0"></a>
<a href="news.html" onMouseOut="MM_swapImgRestore()" onMouseOver="MM_swapImage('Image9','','IMAGES/NEWSA.gif',1)"><img src="IMAGES/NEWS.gif" name="Image9" width="90" height="40" border="0"></a>

</div>

<div id="navbar"> <!-- Being an unordered list means it is easier to update via CSS -->
<ul class="expandable">
<li id="nav-home"> <a href="index.html" title="The Foundation">Home</a> </li>
<li id="nav-training"> <a href="training.html" title="Training">Training</a>
  <ul id="nav-training-sub" style="display:none;"   >
    <li> <a href="training.html#E2E" title="E2E">E2E</a> </li>
    <li> <a href="training.html#ET" title="ET">ET</a> </li>
    <li> <a href="training.html#newdeal" title="New Deal">New Deal</a> </li>
  </ul>
</li>
<li id="nav-housing"> <a href="housing.html" title="Housing">Housing</a> </li>
<li id="nav-outreach"> <a href="outreach.html" title="Outreach">Outreach</a> </li>
<li id="nav-env"> <a href="environment.html" title="Environment">Environment</a> </li>
<li id="nav-credit"><a href="credit.html" title="Credit Union">Credit Union</a> </li>
<li id="nav-info"> <a href="foundationhouse.html" title="Foundation House">Foundation House</a> </li>
<li id="nav-eat"> <a href="eatingpoint.html" title="Eating Point">Eating Point</a> </li>
<li id="nav-review"> <a href="annualreview.html" title="Annual Review">Annual Review</a> </li>
<li id="nav-vacancy"> <a href="vacancies.html" title="Staff Vacancies">Staff Vacancies </a> </li>
<li id="nav-contact"> <a href="contact.html" title="Contact Details"> Contact Details </a> </li>
</ul>

</div>

<div id="content"> 

<p>The Milton Keynes Christian Foundation was established in 1985 by the Milton Keynes Christian Council to address issues and take forward projects in community and economic development. </p>

<p>Over the years, the Foundation has engaged in a range of activities and developed a number of projects, both its own and in partnership with others. </p>

<p>In our activities, we strive to work in partnership with others with whom we share common concerns, for it is, we believe, through partnership that the most creative and exciting solutions often emerge.  Whatever we do, we seek to express the basic belief that all people and all things have an essential value and inherit potential.  Whether through training, environmental concern or community regeneration, we try to work in ways which enable some of this potential to be released.</p>

<p>Our base at Foundation House is home to a number of other organisations, including the Wolverton & Greenleys Town Council, Riselings Parents & Toddlers Group, Tower Drive, etc.</p>

<p>It looks over the Square, which has been re-furbished, that to a grant raised by the Wolverton Partnership from the Single Regeneration Budget.</p>

<p>In recent years, we have worked with range of organisations and individuals on plans to regenerate Wolverton.  We helped found the Wolverton Partnership in 1996 and have assisted the Partnership to obtain two rounds of Government Single Regeneration Budget funding, resulting in �1.5 million being made available to Woverton between 1996 & 2002.</p>

<p>>The money is being used to make a number of improvements to the physical environment, provide childcare facilities, create a range of training opportunities, improve town centre security and support local businesses. </p>


</div>

<div id="footer"> &nbsp;</div>

</div>

</body>
</html>

It may be an Onload conflict - there's a way round that but I can't remember off the top of my head.

Edit: Here's a link to it working (the Home li is a bit far to the right but it works): http://www.littleblueplane.com/test/tph/index.html

My strategy is so simple an idiot could have devised it!

"Also, your CSS (no offence) makes me want to gouge my eyes out with a rusty spoon" - TPH

HellsBells
HellsBells's picture
Offline
Leader
Bedford, UK
Last seen: 13 years 25 weeks ago
Bedford, UK
Joined: 2004-04-07
Posts: 851
Points: 0

JS Show/Hide menu

I did notice that although it's working you can still see a flicker on the transition from closed to open commented on earlier.

It seems to be an echo of the main content section (if you try it with block level elements outlined in FF you can see the red/green lines echoed).

My strategy is so simple an idiot could have devised it!

"Also, your CSS (no offence) makes me want to gouge my eyes out with a rusty spoon" - TPH

thepineapplehead
thepineapplehead's picture
Offline
Guru
Last seen: 4 weeks 7 hours ago
Timezone: GMT+1
Joined: 2004-06-30
Posts: 9674
Points: 810

JS Show/Hide menu

The onload thing is for the image rollovers; I don't even think they'll need them any more.

That seems to have fixed it up a treat.

One more thing though - is there anyway to use the actual anchor as the toggle and remove the code inserted before it?

Thanks again HB, you're a star.

Verschwindende wrote:
  • CSS doesn't make pies

HellsBells
HellsBells's picture
Offline
Leader
Bedford, UK
Last seen: 13 years 25 weeks ago
Bedford, UK
Joined: 2004-04-07
Posts: 851
Points: 0

JS Show/Hide menu

Had a look - the JS's seems pretty deep and daunting - Gary could no doubt manage it - it's waaaay beyond me I'm afraid!!

It all seems to turn on the + or - so I can't see off the top of my head how to remove them. Plus it's all Parent and child node stuff - I need to lie down...

My strategy is so simple an idiot could have devised it!

"Also, your CSS (no offence) makes me want to gouge my eyes out with a rusty spoon" - TPH

thepineapplehead
thepineapplehead's picture
Offline
Guru
Last seen: 4 weeks 7 hours ago
Timezone: GMT+1
Joined: 2004-06-30
Posts: 9674
Points: 810

JS Show/Hide menu

Hehehe Laughing out loud

Well thanks anyway, I'll wait for Gary.

Hells, you're an absolute star. Thanks.

Verschwindende wrote:
  • CSS doesn't make pies

gary.turner
gary.turner's picture
Offline
Moderator
Dallas
Last seen: 33 weeks 3 days ago
Dallas
Timezone: GMT-6
Joined: 2004-06-25
Posts: 9776
Points: 3858

JS Show/Hide menu

If you're thinking something elegant might come along from me, don't hold your breath. Smile

You might notice I'm kind of a brute force kinda programmer.

This code is not at all elegant and it doesn't scale past the one subset. If you only go one sub menu deep, this may work for you.

 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
 
<html xml:lang="en" 
      xmlns="http://www.w3.org/1999/xhtml" 
      lang="en"> 
<head> 
  <meta name="generator" 
        content=" 
        HTML Tidy for Linux/x86 (vers 12 April 2005), see www.w3.org" /> 
         
  <meta name="editor" 
        content="Emacs 21" /> 
  <meta name="author" 
        content="Gary Turner" /> 
  <meta http-equiv="content-type" 
        content="text/html; charset=iso-8859-1" /> 
 
  <title>pop-out menu</title> 
 
<style type="text/css"> 
/*<![CDATA[*/ 
 
html, body { 
    margin: 0; 
    padding: 0; 
    } 
 
ul { 
    margin: 0; 
    padding: 0; 
    list-style: none; 
    } 
 
ul ul { 
    padding-left: 25px; 
    } 
 
li { 
    margin: 3px 0; 
    } 
 
#navcol { 
    width: 100px; 
    margin: 5px; 
    padding: 5px; 
    font: .7em/1.5 tahoma, sans-serif; 
    color: black; 
    background-color: #ccc; 
    border: 2px outset #888; 
    } 
 
#navcol a { 
    display: block; 
    position: relative; 
    color: black; 
    text-decoration: none; 
    border: 2px solid #ccc; 
    cursor: default; 
    _height: 1px;   /*lazy IE white-space bug fix*/ 
    } 
 
#navcol a:hover { 
    border: 2px outset #888; 
    background-color: #ddd; 
    } 
 
#navcol a:active { 
    border: 2px inset #888; 
    color: white; 
    background-color: #999; 
    top: 1px; 
    left: 1px; 
    } 
 
/*]]>*/ 
</style> 
<script type="text/javascript"> 
//<![CDATA[ 
 
function setup(){ 
   document.getElementById("nav-training-sub").style.display="none"; 
   document.getElementById("nav-housing-sub").style.display="none"; 
} 
 
function toggle(trigger){ 
   var sublist = trigger + "-sub"; 
   var e = document.getElementById(sublist); 
   if (e.style.display != "block") 
      e.style.display="block"; 
   else 
      e.style.display="none"; 
} 
 
//]]> 
</script> 
</head> 
 
<body onload="setup();"> 
  <div id="navcol"> 
    <ul> 
      <li id="nav-home"><a href="#" 
         title="The Foundation">Home</a></li> 
 
      <li> 
 
        <a href="#" 
            id="nav-training" 
            onclick="return !toggle(this.id);" 
            name="nav-training">Training »</a> 
 
        <ul id="nav-training-sub"> 
          <li><a href="#" 
             title="E2E">E2E</a></li> 
 
          <li><a href="#" 
             title="ET">ET</a></li> 
 
          <li><a href="#" 
             title="New Deal">New Deal</a></li> 
 
        </ul> 
      </li> 
 
      <li> 
        <a href="#" 
            id="nav-housing" 
            onclick="return !toggle(this.id);" 
            name="nav-housing">Housing »</a> 
 
        <ul id="nav-housing-sub"> 
          <li><a href="#">Small Flats</a></li> 
 
          <li><a href="#">Big Flats</a></li> 
        </ul> 
      </li> 
 
      <li><a href="#" 
         id="nav-outreach" 
         name="nav-outreach">Outreach</a></li> 
    </ul> 
  </div><!-- end navcol --> 
</body> 
</html>
If styles or javascript is off, the sub menus will appear. The main item that triggers the drop-down should link to a backup menu page.

Wow! I can't believe anyone would look to me for javascript help. Man, they must be pretty sor... Wink

cheers,

gary

If your web page is as clever as you can make it, it's probably too clever for you to debug or maintain.

thepineapplehead
thepineapplehead's picture
Offline
Guru
Last seen: 4 weeks 7 hours ago
Timezone: GMT+1
Joined: 2004-06-30
Posts: 9674
Points: 810

JS Show/Hide menu

Thanks so much guys. Just one thing:

my brute force JS friend up there wrote:
The main item that triggers the drop-down should link to a backup menu page.

What did you mean by this?

Verschwindende wrote:
  • CSS doesn't make pies

HellsBells
HellsBells's picture
Offline
Leader
Bedford, UK
Last seen: 13 years 25 weeks ago
Bedford, UK
Joined: 2004-04-07
Posts: 851
Points: 0

JS Show/Hide menu

I think that means it links to a page with the subsection links on it in the main text area in case they can't see the sublinks in the side menu .

My strategy is so simple an idiot could have devised it!

"Also, your CSS (no offence) makes me want to gouge my eyes out with a rusty spoon" - TPH

gary.turner
gary.turner's picture
Offline
Moderator
Dallas
Last seen: 33 weeks 3 days ago
Dallas
Timezone: GMT-6
Joined: 2004-06-25
Posts: 9776
Points: 3858

JS Show/Hide menu

What triggered the comment is that a click on the top, Training, link sends you to a page with a single link to a pdf doc. But, if the submenu doesn't show up (for whatever reason) there is no way to get to where they point.

The top level menu item should link to a page that contains normal links to all the sub menu items.

The way I did this, that may not really be necessary since if js or styles is off, the whole set shows up and links normally. What if, though, styles are on, js is on, but the dropdown function fails? That should cause 'training' to act as a normal link, which should take you to a page with all the links. Graceful failover.Smile

cheers,

gary

If your web page is as clever as you can make it, it's probably too clever for you to debug or maintain.