Link to home
Start Free TrialLog in
Avatar of AlunCarp
AlunCarp

asked on

Popup Menu

I want to create a popup menu on my page similar to the ones used by Microsoft and similar companies.

Can anyone help with ideas, source etc.
Avatar of rafistern
rafistern

What does a "popup menu" look like? Is it a window with the menu inside it?

Please, more information.
Avatar of AlunCarp

ASKER

Basically I want to have a link that when clicked a popup menu appears with related links on.

When an item on the popup is then clicked it takes you to the relevant page.

BTW, must work in both IE and Netscape. Dont mind JavaScript or HTML.
This is your code

<a href="javascript:openFirstMenu()">first link</a>

<script language=javascript>
function openFirstMenu(){
  newWindow=open("","nw","toolbar=no,location=no,directories=no, status=no,menubar=no,width=400,height=400);
  newWindow.document.open();
  newWindow.document.write("<html><head><title>My Title</title></head><body>");
  newWindow.document.write("My Menu");
  newWindow.document.write("</body></html>");
  newWindow.document.close();
}
</script>

The document.open() and close() open and close a stream tot he window which you write html to. This will work on IE3+ and NS3+.

This looks feasible, I will have a look at it later.

A question though:

How do I get links into the new window which then open pages in the caller window and close the menu?

Also, I can remember reading something about this somewhere with some pointer to Microsofts way, I'm not sure if it was here or somewhere else, can anyone remember a similar thread and what the result was.
<a href="javascript:opener.location.href='newURL';"> will open the link in the opener page.


Not really what I had in mind. This creates a new browser window which contains my menu, can be given a funky background and made to look nice. However, I dont really want to have to open a new browser window to display the menu.

What happens if the user keeps the menu browser open and closes the caller browser? It wont be around to be navigated with.

I could consider using a Java applet if one which works with both IE and Netscape can be done?
Java applets will (should) work in any Java compatible browser.
More likely - they just won't work.

A solution (which will only work in IE4) would be to use

<DIV NAME=whatever> Put menu in here </DIV>

And Jscript / DHTML / whatever MS call it this week at the top setting whatever.visible to false.
Also use positioning to make sure its kinda near your link.
Then make the onMouseEnter of the link to set whatever.visible = true; and onMouseExit of whatever to whatever.visible = false.
That should work - it'll overlay onto anything by the side of the link - and only appear while you're hovering.

Unfortunately, only an IE4 solution.

Shame that the 'hidden list' (where bits of the list expanded when you clicked on headings) dissapeared, they'd have been perfect.

Compatible solutions-
The browser window is a nice idea, but a bit clunky on resources.
How about a frame? I assume you've thought of that.
Put a <FORM><INPUT TYPE=Image></FORM>
in the middle of thepage, surrounding by the links you want pop-up behaviour of.
Set their onMouseOver to load new images into it - and give it corresponding onClick handlers.

What I've seen in a page is something trying to look like a standard windows dropdown menu.
I'd do that by having each menu a frame, with clicking on each image loading a new frame into the lot of them, so removing one expanded menu, and bringing down a new one.
Lots of very similar HTML, but a simple, browser compatible solution.
Bet it clunks though.
(Also, if some of your menus are likely to be long, then it'll waste space while not in use)
You could do this with Java but there is the problem that Java adds a big overhead to the loading time of the page and can frequently crash the browser and maybe the whole OS (especially, from my experience, NS4).

If someone closes the parent browser window then obviously he won't be able to navigate in it. In order to close the menu window if he browses on to another page, you can put in a onUnload="newWindow.close()". This will make sure the menu window is closed. You could put the same in the openMenu function in order to close any other menus that may already be open.

In JavaScript 1.2 you can specify that the opener window not be closed until the opened one is, but this would only cover you for generation 4 browsers.

In IE4/NS4 you can also use DHTML to superimpose a popup menu over the page. This is probably what you are refering to. However this leaves the people with legacy browsers without a menu.

You would this like this

<div id="menu1" style="display:none; position:absolute; top:100px; left:100px; z-index:2;">
The menu....
<a href="javascript:document.all.menu1.style.display='none';location.href='newURL';">a menu choice</a>

</div>

<a href="javascript:document.all.menu1.style.display=''">The link to open it</a>

For Netscape you write document.layers instead of document.all

The z-index makes sure it is on a layer above the rest of your text. The display attribute displays and hides it.
Vitenka

I dont quite understand what you mean. Could you provide me with some sample HTML or the URL of a page that does what you say.

rafistern

I think you might be right about the IE4 DHTML thing, I use IE4 at both home and work so wouldn't really have noticed things being browser specific, they would have just happened.
Vitenka,

Unfortunately your solution is only IE4 and I did state that I wanted to use IE and NS and not be restricted to the latest versions either. Its also possible that people will use other browsers and they need support too.

I didn't want to use frames either if I could avoid it.

I think I'll put this down as one of those dreams that wont come true :)
Sorry Vitenka, just checked the text of my question and it doesn't state browsers at all.

I shall try to be clearer in future.
Well you could have two versionsof
what you could do is to is to replace an image and put a map on the image...
so you have an imagemap:
<map name="myimgmap">
  <area shape="rect" href="javascript:'loadpage(1)'" coords="20,20,70,60">
  <area shape="rect" href="javascript:'loadpage(2)'" coords="90,20,140,60">
  <area shape="rect" href="javascript:'loadpage(3)'" coords="20,80,70,120">
  <area shape="rect" href="javascript:'loadpage(4)'" coords="90,80,140,120">
  <area shape="default" href="javascript:'loadpage(5)'">
</map>

and then you have to javascript functions:

<script language="JavaScript">
imagename = "place"                                                 // name in an IMG tag
var actArray = new Array();                                         // active array
var lnkArray = new Array("link1","link2","link3","link4",null);  //array with the links
var notArray = new Array(null,null,null,null,null);                  //array with nulls
var noimg = new Image();                                           //preload the blank image
noimg.src = "blank.gif"                                              //this is a blank gif picture
var menuimg = new Image();                                           //preload the menu image
menuimg.src = "menu.gif"                                              //this is a menu gif picture

/* This is the function launched by the map, if it's not a null link, the change the windows location */
function loadpage(page){
  if (actArray(page)!=null){
    this.location.href=actArray(page);
  }
}
/* This is the function to activate the menu, what it does is to change to the real link and change the image so that you see the menu */
function activateMenu(){
  actArray = lnkArray;
  document.images[imagename].src=menuimg.src;
}
/* This is the function to set all things that were altered in activateMenu back to original */
function deactivateMenu(){
  actArray = notArray;
  document.images[imagename].src=blankimg.src;
}
</script>

all you have to do now is add an imagebox which would represent the placing of the menu...
the label has to be outside the image...
this is one of the few ways to do this in all browsers compatible with JavaScript...

but then, it wouldn't be a popup menu, as the place where it's located has top be empty when the menu is deactivated....

hope this is what you want...

// Gustav
Hi Grdv

As the comment as the end of your answer states, 'the place where it's located has to be empty when the menu is deactivated....', this would make the page look very patchy and untidy.

I think from the little testing I've been able to do that I will discard this idea in order to maintain support for older browsers.
well I realised myself that MSIE 3 is not compatible with the document.images method..
the only possabilty which is compatible i even elder browsers I think is to completely change the page source.

You could use open child command in js and have a child window that has
no menu etc and but it will only remain open as long as the creator (parent) window
stays open.

CJ
Hi cheekycj

That sounds just like the answer rafistern suggested right back at the beginning.

I dont know about anyone else but it does annoy me a bit when I go to a site and extra browser windows open when I get there. This type of behaviour I would like to avoid in my pages.

Thanks anyway.
Check this out... This is a DHTML menuing system that works in both IE and NS and could very easily be manipulated to work as popups...  What do you think?

http://www.webreference.com/dhtml/column21/addendum/
Hi MasseyM

Great site, great ideas, loads of info.

Unfortunately DHTML requires the later breeds of browser and restricts you either IE or NS.


This is microsofts...

<STYLE>
            'A.mw:link      {color:white; font-weight:bold;font-size:9px;text-decoration:none;}' +
            'A.mw:visited      {color:white;}' +
            'A.mw:hover            {color:red;}' +

</STYLE>

<SCRIPT TYPE="text/javascript">

      function doMenu(id, x) {

            var thisMenu = document.all(id);
            if (useragent.indexOf("Windows 3.1") != -1) {
                  if(x > 0) {
                        x = x * .80;
                  }
            }
            if (useragent.indexOf("X11") != -1) {
                  if(x > 0) {
                        x = x * .7;
                  }
            }

            if (thisMenu == AnimatedMenu) {
                  window.event.cancelBubble = true;
                  return false;
            }
            if (AnimatedMenu != null) AnimatedMenu.style.display = "none";

            window.event.cancelBubble = true;

            if ((id == "MsftMenu") || (id == "MsnMenu")){
                  thisMenu.style.top = 18;
            }else{
                  thisMenu.style.top = 15;
            }
            if( x < 0) {
                  x = document.body.clientWidth + x;
            }
            thisMenu.style.left = x;
            AnimatedMenu = thisMenu;
            if(useragent.indexOf("Mac") != -1) {
                  AnimatedMenu.style.display = "";
            }
            else {
                  thisMenu.style.clip = "rect(0 0 0 0)";
                  thisMenu.style.display = "block";
                  nChunk = 25;
                  window.setTimeout("showMenu()", 30);
            }
            return true;
      }

      function showMenu() {
            AnimatedMenu.style.clip = "rect(0 "+ nChunk + "% " + nChunk + "% 0)"
            nChunk +=25
            nChunk<=100?window.setTimeout("showMenu()",25):null      
      }

      function hideMenu(){
            AnimatedMenu.style.display = "none";
            AnimatedMenu = StartMenu;
            window.event.cancelBubble = true;
      }

      function keepMenu(){
            window.event.cancelBubble = true;
      }
      
      function hideMH()      {
            makehome.style.display='none';
      }
      
      document.onclick = hideMH;
      document.onmouseover = hideMenu;
      window.onerror = HideErrors;

</script>

<SPAN ID='MsnMenu' onMouseover='keepMenu();' STYLE='width:160;padding-left:0;padding-bottom:7;display:none;position:absolute;background-color:black;z-index:9;'>
      <A CLASS='mw' target=_top HREF='http://home.microsoft.com/'>&nbsp;&nbsp;Internet Start</A> <BR>
      <A CLASS='mw' target=_top HREF='http://network.msn.com/hotmail/hotmail.asp'>&nbsp;&nbsp;Hotmail</A> <BR>
      <A CLASS='mw' target=_top HREF='http://www.msnbc.com/xnav/default.asp'>&nbsp;&nbsp;MSNBC</A> <BR>
      <A CLASS='mw' target=_top HREF='http://investor.msn.com/external/imgnav/imgnav.asp'>&nbsp;&nbsp;Microsoft Investor</A> <BR>
      <A CLASS='mw' target=_top HREF='http://expedia.msn.com/snav/default.asp'>&nbsp;&nbsp;Expedia.com Travel</A> <BR>
      <A CLASS='mw' target=_top HREF='http://network.msn.com/allsites.asp'>&nbsp;&nbsp;More Microsoft Sites...</A> <BR>
</SPAN>

The above code is © 1998 Microsoft Corporation... It is used as an example only... This is what you want?
Hi MasseyM

Will check it out, as it's Microsoft's way will it only work in IE and does it need version 4?
yes, it does need a fourth generation browser... :(

// Grdv
Hi MasseyM

I would ideally like to support browsers other than 'fourth generation', however, that aside I got script error when included in an .HTML page.

The errors were:

    'HideErrors' is undefined

then if I continue running scripts on the page I get:

    'AnimatedMenu' is undefined

Any suggestions?
http://www.willcam.com/cmat/html/crossref.html
goto that website and then click on the menu tag -it should tell you everything you need to know, you can find it all on that site.
Hi sci33

Have had a quick look at the site, haven't had a chance to try it yet though.

From reading what is there does using the <MENU> tag create a menu list or does it create a menu that 'pops up'.

It is the 'pop up' effect that I am trying to achieve.
Hi sci33

Have tried the <MENU> tag and as suspected it puts a list of items on the page and does not create a 'pop up' menu.

The reason for the 'pop up' menu is to save space on pages and to make navigation a little more intuitive :)

i know you've already rejected the idea posed by Gdrv, but i want to second his opinion about using the pop down image map method.   You say that the sight would be very "clunky" but that doesn't have to be.  check out www.supra.com for a very nice implementation that only requires a 3.0 browser.  You could reverse the idea, having the images pop up above the main link, and that would work well if the main link was placed at the top of the page... especially if you did something like border the entire page in one color so that when the menus were hidden, the main text of the page would appear in the center, padded by a single color on all sides.  Aside from that, you would have to go either w/ the CSS idea which requries a 4.0 browser, or the alternative would be a simple form pop up menu.  that however would requrie going through a cgi-bin and might look kinda clunky as well.
Hi Timbuk3

You're right, using an image in this way does look kinda cool.

Sometimes what you visualise is not quite what can be done. Will give it a go when I get the chance then I'll need to work out who may get the points :)

If it works in 3.0 browsers then I would be reasonably happy :)
It's a nice way of doing what I suggested, the main difference is that this images have their image maps on the image which is, what you could call the menu button... and therefore you don't need code that goes nowhere when the user clicks the unactive menu.
and that's better in some cases worse in some...

about the points, doesn't really matter who get's them, what important is that the problem is solved, even though I was the one presenting a solution like this one in the beggining...

//Grdv
Hi Grdv

Now that I have a bit of time I will try this suggestion and your previous one to see which I like the look of and does the job best. After all, with the WWWeb its the look and feel that is most important :)

Your right, the important thing about a problem is the satisfactory solution.
uhh.... sheeesh!!!!
I would like a menu that appears to materialize slowly fourteen colors of the rainbow with dancing pigs on it... and it has to be supported by the earliest neanderthal versions of IE, NN, and also in text only browsers.
bumpypigg wrote:
>uhh.... sheeesh!!!!
 >     I would like a menu that appears to materialize slowly fourteen colors of the rainbow >with dancing pigs
 >     on it... and it has to be supported by the earliest neanderthal versions of IE, NN, and >also in text only
 >     browsers.

Write it in Java, I also saw someone mentioning applets are a "load hog" and "crashes OS'es"
I would suggest not loading applets written by amateurs who don't know the first thing about java.

I have a pop-up written in java and it works like a charm!!

Contact me of list/exchange/whatever and I'll see what i can do for ya.
I haven't followed all ansers and comments at this question, but is it this you are looking for?

<FORM>
<SELECT NAME="list">
<OPTION SELECTED VALUE="http://www.coffeecup.com/editor">CoffeeCup Editor
<OPTION VALUE="http://www.netscape.com">Netscape
<OPTION VALUE="http://www.microsoft">Microsoft
<OPTION VALUE="http://www.infoseek.com">Infoseek
</SELECT><P>
<INPUT TYPE=BUTTON VALUE="Go Get It!"
onClick="top.location.href=this.form.list.options[this.form.list.selectedIndex].value">
</FORM>

Luck!!! Michel
Hi Michel

Will probably work but not what I had in mind.

If you read through the history you will see where the thread is going, I think I will probably use an Image Map to provide the menu as per Grdv's suggestion. I am still checking it out at the mo', have a lot of other work to do so not much time for Web prettiness.

Thanks

Sure about your answer yet??
//Grdv
Sure about how you want it yet??
//Grdv
oops
Grdv

As soon as I have it sorted I'll get back to you all.


The only way to be sure that all browsers (old and new) can be supported is to resort to server side scripting or just plain HTML. Now, whatever way you want to implement it is your own problem since "browsers" such as Lynx (text-browser) does not support certain tags such as TABLE which is quite useful for formatting the screen.  For all I care, you can write one page for each and every menu items to show exactly how you want them to look like.  Now, if you have 6 menu items that would make 6 pages just to show the submenu of each parent's menu item.  That will accomplish what you want (I hope)...a pop up menu that will refresh the screen each time you click on an item and compatible with all browser old and new.  Heck, why not just do a text link?

[ Item 1 | Item 2 | Item 3 ] ????

Now, if you want the latest state of the art menuing that can do a whole bunch of stuffs (chuckle -- bumpypigg), you better believe it...IT WILL NOT SUPPORT ALL BROWSERS OLD AND NEW.  That means you have to sacrifice old browsers and specific new ones.  Too bad for those oldtimers that are still clinging to the ancient browsers, too bad for those that have chosen this browser over that browser.  Life is tough.  Take a choice and live with it.

Now, if you have a whole lot of time on your hand (whoopeedoo), you can create each solution independently (one that works with Lynx, one that work w/ netscape 1.0, one that work with netscape 2.0, one that work with ie 1.0, one that work with ie 2.0, etc. etc.).  Again, it'll come down to choices. Take a choice and live with it.

Don't you think that setting a minimum requirement for a page is a more reasonable way to handle this?  If the page really need IE4 to run, then let the user know that this page is specifically designed for IE4 and therefore give them an option to download and install IE4.  If they choose not too, hey, it's their lost.  Take a choice and live with it.

Nuff said.  Sorry if this sounds harsh, but that's the reality of the web.
Hi PBall, bumpypigg and all who want a browser specific Web,

"Anyone who slaps a 'this page is best viewed with Browser X' label on a Web page appears to be yearning for the bad old days, before the Web, when you had very little chance of reading a document written on another computer, another word processor, or another network."

         Tim Berners-Lee in Technology Review, July 1996

I support a non browser specific web and as such want any site I produce to be viewable by the majority. If this means text only browser support then thats what I'll have to do.

Check out http://www.antbrowser.org/campaign/
Then your answer are already given in my previous post.
Use the least common denominators of all browsers including text only.  No fancy stuff.
And another thing. I didn't say that I want the web to be only for specific browser.  I said it is time to take a choice and live with it.  I am not forcing the web to be only for IE4 or Netscape or Lynx, the surfer still have a choice. I am not sure how it is with other people but with me.. I have both browser handy (N4.5 and IE4.01) eventhough I use IE4 most of the time, but when I can't, I switched to N4.5 to view a N4.5 enchanced site if I really want to see it in its full glory.  It's all come down to choice.

"Anyone who slaps a 'this page is best viewed with Browser X' label on a Web page appears to be yearning for the bad old days, before the Web, when you had very little chance of reading a document written on another computer, another word processor, or another network."

         Tim Berners-Lee in Technology Review, July 1996

1. Hehe :) Nothing has changed since that time, things just get a bit more wee complicated, Mr. Berners-Lee there need to wake up and smell the coffee.  When the web is trully unified and standardized (again, this can be achieved without having to make the web viewable by only IE or only by Netscape.  The browsers might be different but the features can be the same) then and only then his dream will come to its fullest (assuming that he wants to be able to view all the information with any browser and having all the information appear equally in any ways possible).

2. Technology keeps changing.  To stay behind at certain point = asking to be left behind.  Moving with certain technology can put you on the cutting edge but at a price of a sacrifice.  This is true with the web.  Ever heard of a proverb saying you cannot hold a charging train with just a finger and standing still? Well, now you have.  Here is another one:  Swimming in an endless ocean.  You stop swimming, you die, you swim you die of fatique, you don't do anything, you die.  So pick your choice. Either/Any way, you'll die.  So what do you do? you choose something and stick with it.
PBall, the most common browsers are NS4, NS3 and IE4 and then there's about 10% using other browsers and among them mostly IE3.
just wonder why you need to pull evrything over one line... I mean ither you want the latest stuff or nothing...
but then ither you get a web that is just viewable for 80% of the net (NS4&IE4) or maybe half of that if make a version that is only IE or only NS compatible.
And if you can't have the latest then you want a text-version... if you want a text-version, then tell me why you use the 4th gen browsers.. Mosaic goes perfectly well for text only browsing...
aren't web-page designers supposed to make something that is compatible with most browsers and looks very well... and then if the group you target with your page would use a text-only browser then make it compatible with that...
look at my page:
http://home1.swipnet.se/~w-10109/msh/
it's compatible with all browsers that can handle images and tables, and possibly you'll get error messages in a browser without the dynamic.images method availiable...
well, what is it about that page, well it works, looks as good as it has to do and if you consider that the target-group are all javascript-programmers then I don't think there really is a compatibility problem... as most javascript-programmers work with Netscape, as they invented JavaScript.
think that was about all for now...
//Grdv
aren't web-page designers supposed to make something that is compatible with most browsers and looks very well...

Yes and I agree with that.  But if you want (disregarding the audience for now) some features that are only implemented in this or that version of this or that browser, then you have to sacrifice the older ones (meaning they won't be able to see it implemented correctly).  That was the point that I was trying to get across.

it's compatible with all browsers that can handle images and tables, and possibly you'll get error messages in a browser without the dynamic.images method availiable...

You've just stated my point.  In this example IE3 can't change images on the fly.  So IE3 will not be supported for that feature.

Now, if you want your page to be backward compatible with IE3 then get rid of the dynamic image changes altogether or develop different versions of the pages to run correctly on each version/type of browser.  Either way, IE3 still can't do dynamic images.  Again..hmm..feature or compatibility? take a choice and live with it.

I am advocating for future browsers because I can see in my head that sooner or later the older browsers will die and people will move to a more current up-to-date browsers.  You might as well move forward and learn something new instead of staying static and wait for your death (not literally of course, career maybe...).  If that means losing some of your current audience than so be it.  It is one choice.  You may choose to take it or not.  If you would rather spend some transition time, then your option is to support both old and newer browsers (perhaps with the least common denominator method or multiple version of the page).  It is also a choice.  You may take it or leave it.  And yet another choice is to go full force with the latest and greatest technology.  It is a choice too.  Take a pick.  

And again, realize that each choice comes with its own consequences.

If you choose compatibility with older browsers then you can forget using the latest technology.

If you choose compatibility with maintaining different page versions then be prepare to lose some time coding different versions.

If you choose to use the latest tech, then say goodbye to the people who are still using the older browsers or give them a choice to upgrade theirs.

Any which way you choose does not matter as long as you choose and accept the tradeoffs.

Again, sorry if I offend anyone.  I am not trying to hurt anybody's feeling by posting this.  I am just stating the obvious.
Check This;

<HTML><HEAD>
<TITLE>DHTML Pop-up Menu</TITLE>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=iso8859-1">
<META NAME="MS.LOCALE" CONTENT="EN-US">
<META NAME="ROBOTS" CONTENT="all">
<!-- Copyright 1997. Microsoft Corporation. All rights reserved. -->

<style>
menuBorder1 {
  position:absolute;
  left:-1000; top:-1000;
  background-color:#C6C3C6;    /* light gray */
  border: solid 1px;
  border-left-color:#C6C3C6;   /* light gray */
  border-top-color:#C6C3C6;    /* light gray */
  border-bottom-color:black;
  border-right-color:black;
  margin:0 0 0 0;
  overflow:none;
  visibility:visible;
  }

menuBorder2{
  position:absolute; top:0; left:0;
  background-color:#C6C3C6;    /* light gray */
  overflow:none;
  margin: 4px 0px 4px 0px;
  border: solid 1px;
  border-left-color:white;
  border-top-color:white;
  border-bottom-color:#848284; /* dark grey */
  border-right-color:#848284;  /* dark grey */
  cursor:default;
  }

menuTable {}

menuRow {
  font-family: MS Sans Serif;
  font-size: 9pt;
  color:black;
  background-color:transparent;
  cursor:default;
  height:12pt;
  }

menuImageCell {
  text-align:left;
  cursor:default;
  }

menuCaptionCell {
  text-align:left;
  cursor:default;
  }

menuArrowCell {
  text-align:right;
  font-size: 8pt;
  cursor:default;
  }

#MENUINSERT {
  position:absolute;
  top:0; left:0;
}
</style>

<script>
<!--
var menus = new Array()

function MenuRegister(item)
{
  menus[menus.length] = item
  return (menus.length - 1)
}


//*****************************************************************************
// Function:   MenuItem
// Arguments:  caption   -- a string to be used for the menu item caption
//             command   -- a url string or a function reference
//             image     -- a url to a 16x16 image.  Pass in null for no image
//             submenu   -- a reference to a Menu object.  It will display the
//                       -- arrow to the right of the caption and display the
//                       -- submenu. Pass in null for no submenu
//             separator -- (true|false) display this menu item as a line
// Purpose:    For each menu item in a menu, there is one MenuItem object to
//             describe it.
//*****************************************************************************

function MenuItem(caption, command, image, submenu, separator)
{
  this.caption = caption;
  this.command = command;
  this.image = image;
  this.submenu = submenu;
  this.separator = (separator) ? true : false;
  this.id = MenuRegister(this);
}

//*****************************************************************************
// Function:   MenuItemOnClick()
// Arguments:  obj  -- This is always a reference to the table row for the menu
//                     item.
// Purpose:    When the user clicks on a menu item, the table row will call
//             this function.  If the MenuItem.command is a function, it gets
//             run, and if it is a string (url), the window.location gets set
//             to it.
//*****************************************************************************

function MenuItemOnClick(obj) {
  var item = menus[obj.menuid]
  var menub1 = document.all['MENU' + item.parent + 'B1']

  window.event.cancelBubble = true

  if (item == null) return

  if ((typeof item.command) == 'function') item.command()
  if ((typeof item.command) == 'string') window.location = item.command
}

//*****************************************************************************
// Function:   MenuItemOnMouseOver()
// Arguments:  obj  -- This is always a reference to the table row for the menu
//                     item.
// Purpose:    This is the onMouseOver event for the menu table rows.  It will
//             highligh the row and display the submenu if there is one.
//*****************************************************************************

function MenuItemOnMouseOver(obj) {
  var item = menus[obj.menuid]
  var parent = menus[item.parent]
  var menub1 = document.all['MENU' + item.parent + 'B1']
  var fromElement = window.event.fromElement
  var toElement = window.event.toElement

  window.event.cancelBubble = true

  // If just moving around within the row, then return
  // This improves performance and avoids a flicker
  if ((fromElement != null) && (toElement != null))
  {
    if (fromElement.menuid == toElement.menuid) return;
  }

  obj.style.backgroundColor = '#000084'  // Change background to dark blue
  obj.style.color = 'white'              // Change text to white


  // If a submenu is open that is not for this menu item, close it
  if ((parent.submenu != null) && (parent.submenu != item.submenu))
  {
    parent.submenu.hide()
    parent.submenu = null
  }

  // If this item has a submenu, open it
  if ((item.submenu != null) && (parent.submenu != item.submenu))
  {
    item.submenu.top = menub1.offsetTop + obj.offsetTop;
    item.submenu.left = menub1.offsetLeft + obj.offsetWidth;
    item.submenu.show()
    parent.submenu = item.submenu
    return;
  }

}

//*****************************************************************************
// Function:   MenuItemOnMouseOut()
// Arguments:  obj  -- This is always a reference to the table row for the menu
//                     item.
// Purpose:    This is the onMouseOut event for the menu table rows.  It will
//             return the row to a non-highlighted state and will close the
//             close the submenu unless the mouse was moved over to the submenu
//*****************************************************************************

function MenuItemOnMouseOut(obj) {
  var item = menus[obj.menuid]
  var parent = menus[item.parent]
  var toElement = window.event.toElement

  window.event.cancelBubble = true

  if ((toElement != null) && (toElement.menuid == parent.id)) {
    if ((parent.submenu != null) && (parent.submenu != item))
    {
      parent.submenu.hide()
      parent.submenu = null
    }
  }

  if ((window.event.fromElement != null) && (window.event.toElement != null))
  {
    if (window.event.fromElement.menuid == window.event.toElement.menuid) return;

  }

  obj.style.backgroundColor = "transparent"
  obj.style.color = 'black'
}

//*****************************************************************************
// Function:   MenuItemToString()
// Arguments:  none
// Purpose:    This is used by the Menu object when creating each row of the
//             menu table.
//*****************************************************************************

function MenuItemToString()
{
  if (this.separator)
    return "<tr><td class=menuSep colspan=3><hr></td></tr>\n"

  return "  <tr class=menuRow \n" +
         "      onMouseOver='MenuItemOnMouseOver(this)'\n" +
         "      onMouseOut='MenuItemOnMouseOut(this)'\n" +
         "      onClick='MenuItemOnClick(this)'\n" +
         "      menuid=" + this.id +
         "      >\n" +
         "    <td class=menuImageCell noWrap=noWrap menuid=" + this.id + ">" +
                 ((this.image != null) ? "&nbsp;&nbsp;<img class=menuImage menuid=" + this.id + " src='" + this.image + "'>&nbsp;&nbsp;" : "&nbsp;&nbsp;" ) + "</td>\n" +
         "    <td class=menuCaptionCell noWrap=noWrap menuid=" + this.id + ">" + this.caption + "</td>\n" +
         "    <td class=menuArrowCell noWrap=noWrap menuid=" + this.id + " " +
           ((this.submenu != null) ? "style='font-family:Webdings'>4" : "style='font-family:times'>&nbsp;&nbsp;&nbsp;") + "</td>\n" +
         "  </tr>\n";
}

MenuItem.prototype.toString = MenuItemToString;

//*****************************************************************************
// Function:   Menu
// Arguments:  top   -- The top coordinate for the menu
//             left  -- The left coordinate for the menu
// Purpose:    This is used to create a menu
//*****************************************************************************

function Menu(top, left)
{
  this.items = new Array()
  this.top = top
  this.left = left
  this.id = MenuRegister(this)
  this.update = true;

  MENUINSERT.insertAdjacentHTML('BeforeEnd', this.borders())
}

//*****************************************************************************
// Function:   MenuAddItem
// Arguments:  item -- a menu item to add to the end of the menu.
// Purpose:    Used to add a new menu item to the end of the menu.
//*****************************************************************************

function MenuAddItem(item)
{
  this.items[this.items.length] = item
  item.parent = this.id
}

//*****************************************************************************
// Function:   MenuShow
// Arguments:  noDisplay  -- use true when the menu is created to initialize
//                        -- the menu
// Purpose:    Menu.show() is called from code to show the menu when needed and
//             Menu.show(true) should be called to initialize the menu.
//*****************************************************************************

function MenuShow(noDisplay)
{
  var menub1 = document.all['MENU' + this.id + 'B1']
  var menub2 = document.all['MENU' + this.id + 'B2']

  if (this.update)
  {
    menub2.innerHTML = this.getTable()
    this.update = false
  }

  var menu = document.all['MENU' + this.id]

  menub1.style.top = this.top
  menub1.style.left = this.left

  menub2.style.width = menu.offsetWidth + 2
  menub2.style.height = menu.offsetHeight + 2
  menub1.style.width = menu.offsetWidth + 4
  menub1.style.height = menu.offsetHeight + 12


  // BUG: some offset factors are used here to compensate for scroll bars and
  //      differences between large and small fonts
 
  // If the menu goes past the bottom of the body, move it up
  if ((menub1.offsetTop + menub1.offsetHeight) > (MenuBodyRef.offsetHeight - 4))
    menub1.style.top = MenuBodyRef.offsetHeight - menub1.offsetHeight - 4

  // If the menu goes past the right of the body, move it left
  if ((menub1.offsetLeft + menub1.offsetWidth) > (MenuBodyRef.offsetWidth - 24))
    menub1.style.left = MenuBodyRef.offsetWidth - menub1.offsetWidth - 24

  // If the menu is too far up, make the top at 0
  if (menub1.offsetTop < 0)
    menub1.style.top = 0

  // If the menu is too far left, make the left at 0
  if (menub1.offsetLeft < 0)
    menub1.style.left = 0

  // BUG: Removing this causes the highlight to be broken up between cells
  MENUINSERT.insertAdjacentHTML('BeforeEnd', "")

  if (noDisplay)
  {
    menub1.style.top = -1000
    menub1.style.left = -1000
  } else {
    menub1.style.visibility = 'visible'
  }
}

//*****************************************************************************
// Function:   MenuHide
// Arguments:  none
// Purpose:    Menu.hide() is called from code to make the menu disappear.
//*****************************************************************************

function MenuHide()
{
  var menub1 = document.all['MENU' + this.id + 'B1']
  if (this.submenu != null) this.submenu.hide()

  // BUG: the use of style.display='none' causes the menu to turn into a
  //      little 5x20px gray block that never again displays correctly

  menub1.style.visibility = 'hidden'
  menub1.style.top = -1000
  menub1.style.left = -1000
}

//*****************************************************************************
// Function:   MenuBorders()
// Arguments:  none
// Purpose:    The borders create the 3D effect and serve as a container for
//             the menu table.
//*****************************************************************************

function MenuBorders() {
  return  "<div id=MENU" + this.id +"B1 class=menuBorder1 menuid=" + this.id + " onClick='window.event.cancelBubble = true'>\n" +
          "  <div id=MENU" + this.id +"B2 class=menuBorder2 menuid=" + this.id + ">\n" +
          "  </div>\n" +
          "</div>\n";
}

//*****************************************************************************
// Function:   MenuTable()
// Arguments:  none
// Purpose:    This creates the HTML table used to represent the menu.
//*****************************************************************************

function MenuTable()
{
  var str

  str = "<table id=MENU" + this.id + "\n" +
        "       cellpadding=0 cellspacing=0 border=0 class=menuTable>\n"

  for (var i=0; i < this.items.length; i++)
    str += this.items[i];

  str += "</table>\n"

  return str
}

Menu.prototype.addItem = MenuAddItem;
Menu.prototype.borders = MenuBorders;
Menu.prototype.getTable = MenuTable;
Menu.prototype.show = MenuShow;
Menu.prototype.hide = MenuHide;

//*****************************************************************************
// Function:   MenuInit()
// Arguments:  none
// Purpose:    This creates the object used to insert the HTML menu objects
//             into at runtime.  It should be called only once, probably during
//             The window's onLoad event and it must be called before Menu()
//             objects are created.
//*****************************************************************************

var MenuBodyRef;
function MenuInit() {
  for(var i in document.all){
    if (document.all[i].tagName == 'BODY')
    {
      MenuBodyRef = document.all[i]
      MenuBodyRef.insertAdjacentHTML('AfterBegin', '<div id=MENUINSERT></div>')
      break
    }
  }
}





// END OF MENU CODE


var mainMenu = null;

function DocOnLoad() {

  var submenu

  MenuInit();

  mainMenu = new Menu(100, 20);

  submenu = new Menu(0,0)
  submenu.addItem(new MenuItem('Windows 95 / NT 4.0', 'http://www.microsoft.com/ie/ie40'))
  submenu.addItem(new MenuItem('Windows 3.1 / NT 3.51', 'http://www.microsoft.com/ie/win31'))
  submenu.addItem(new MenuItem('Macintosh', 'http://www.microsoft.com/ie/mac/ie40'))
  submenu.addItem(new MenuItem('UNIX', 'http://www.microsoft.com/ie/?/ie/platform/unix.htm'))
  submenu.show(true)
  mainMenu.addItem(new MenuItem('Internet Explorer 4.0', null, null, submenu, null))

  submenu = new Menu(0,0)
  submenu.addItem(new MenuItem('Windows 95 / NT 4.0', 'http://www.microsoft.com/ie/ie3'))
  submenu.addItem(new MenuItem('Windows 3.1 / NT 3.51', 'http://www.microsoft.com/ie/win31'))
  submenu.addItem(new MenuItem('Macintosh', 'http://mscominternal/ie/mac/'))
  submenu.show(true)
  mainMenu.addItem(new MenuItem('Internet Explorer 3.0', null, null, submenu, null))

  mainMenu.addItem(new MenuItem('NetMeeting', 'http://www.microsoft.com/netmeeting'))
  mainMenu.addItem(new MenuItem('NetShow', 'http://www.microsoft.com/netshow'))

  submenu = new Menu(0,0)
  submenu.addItem(new MenuItem('Windows 95 / NT 4.0', 'http://mscominternal/ie/ie3/?/ie/most/howto/mailnews.htm'))
  submenu.addItem(new MenuItem('Windows 3.1 / NT 3.51', 'http://mscominternal/ie/win31/features/?/ie/win31/features/imn.htm'))
  submenu.addItem(new MenuItem('Macintosh', 'http://mscominternal/ie/mac/features/?/ie/mac/features/imn.htm'))
  submenu.show(true)
  mainMenu.addItem(new MenuItem('Internet Mail and News', 'http://msw', null, submenu))
 
  mainMenu.addItem(new MenuItem('Microsoft Chat', 'http://www.microsoft.com/ie/chat'))
  mainMenu.addItem(new MenuItem('Administration Kit', 'http://www.microsoft.com/ie/ieak'))

  mainMenu.addItem(new MenuItem(null, null, null, null, true))

  mainMenu.addItem(new MenuItem('Find on Internet', 'http://www.infoseek.com', '/msdn/sdk/inetsdk/samples/dhtml/dhtmlmenu/find.gif'))
  mainMenu.addItem(new MenuItem('Cancel', new Function('DocOnClick()'), '/msdn/sdk/inetsdk/samples/dhtml/dhtmlmenu/x.gif'))
  mainMenu.show(true)
}

var flag = false
function DocOnClick() {
  if (flag) {
    mainMenu.hide()
  } else {
    mainMenu.left = window.event.x
    mainMenu.top = window.event.y
    mainMenu.show()
  }
  flag = ! flag
}
-->
</script>

</HEAD><BODY onLoad="DocOnLoad()" onClick="DocOnClick()" TOPMARGIN=10 BGPROPERTIES="FIXED" BGCOLOR="#FFFFFF" LINK="#000000" VLINK="#808080" ALINK="#000000">
<!--TOOLBAR_START-->
<!--TOOLBAR_EXEMPT-->
<!--TOOLBAR_END-->
<FONT FACE="VERDANA,ARIAL,HELVETICA" SIZE="2">
<H3>DHTML Pop-up Menu</H3>
Click the <i>left</i> mouse button anywhere on this page to activate
a pop-up menu implemented using Dynamic HTML.
</FONT>
</BODY>
</HTML>

I didn't really want to provoke a discussion on the way the web is going.

In my opinion, using currently ratified standards <bg> is probably the best thing to do, the reason why some sites are best viewed with IE4 or N4.5 is because the standards and technologies they use haven't been, or even wont be, agreed upon.

I believe HTML 3.2 is currently agreed so coding a site to HTML 3.2 is what I aim to do, providing a text only page for browsers which don't support HTML 3.2.

I think the image map idea is what I'll go for which also requires JavaScript, I am not sure which standard is agreed on as yet but again any browser which doesn't support JavaScript can use the text only pages.
Check out my answer.  It is a popup fromm Microsoft.
Hi MasseyM

I dont want to get into this debate again, using Dynamic HTML puts me down one specific road and until even the major players can agree on DHTML it's a road I'll not be travelling.

The MS code will probably be sort of OK in MSIE 4, not so good in N4.5 and fail miserably in evrything else.
Wow 3 months and no expert can help.  That is pretty pathetic :)

Have a nice day
Hi MasseyM

>Wow 3 months and no expert can help.  That is pretty pathetic :)

The main reason it has taken so long is that this HTML stuff is being in any spare time I have. The problem with spare time is that there isn't very much of it.


I understand spare time.  However, YOu have had SO MANY good answers it is ridiculous.  They are all feasible answers!  You will never get a "pop-up" menu like you want. Period.
Hi MasseyM

> You will never get a "pop-up" menu like you want. Period.

I know. Period.

As far as I can see I have had basically ONE GOOD answer which can be used farely reliably across a variety of browsers.

I have also had a FEW OK answers which are browsers specific, or require tweeking for different browsers. I say OK because although the answers may be good, if I was a fan of IE4 or N4.5 which I am not, I use Opera for preference, they are as I said fairly specific.

As I said, as soon as I have SPARE TIME I will check them all out although anything which wont work in Opera or IE3 without tweeking will be rejected immediately.

I suggest looking at this website:
http://www.insidedhtml.com/tips/task/cat23.asp

It has different kinds of popup menus.
Hi poohbear_68

This is a fine example of DHTML and if I wanted to use DHTML this would have been good. However, I still want to remain in the dark ages :) and use HTML for this.

Perhaps if we keep this thread going long enough everyone on the web will be using browsers which adheres to a known standard which would then enable fussy people like me actually do something instead of moaning about lack of standards or adherence to them.

Until then I think I'll stick with ratified HTML thanks.

AlunCarp
ASKER CERTIFIED SOLUTION
Avatar of webguy
webguy

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial