PDA

View Full Version : cnnfn.com menu



kamakazi
09-29-2006, 02:01 PM
Hi, I need to use the menu like the one on cnnfn.com, only with multiple levels. Is this possible. I need my top level menu to be in a table like cnnfn.com

Kindly please help me.

Thanking you in advance.

mburt
09-29-2006, 02:15 PM
Well I can tell you up front: We're not just going to make a multi-level menu out of thin air, mainly because there are multi-level menus out there. There's a couple on DD even.
Please try looking around a bit before asking us to do it.

kamakazi
09-29-2006, 02:28 PM
Sorry, I didn't mean to upset you. I am new to javascript so all the multi level menus that I have seen so far are using <Li> and <lu> so I didn't know how to past that in to a table. I am sorry again.

mburt
09-29-2006, 02:43 PM
No, no, no. I didn't mean to be er... upset with you. I was just trying to say that there are menus out there that you can get. And I am sorry if I was a little rude.

Okay. For one, that site isn't using tables. Their using some sort of container, most likely a <div> tag.

I'll try to implement a menu similar to one on that site :)

mburt
09-29-2006, 03:20 PM
Okay. I have a short implentation of it:

http://mburt.mb.funpic.org/test/cnn_menu.htm

The only difference is that it doesn't delay the onmouseout feature.

Save the following as "menu.js"

function showmenu(orig,elem) {
var obj = document.getElementById(elem)
var padding = 1
if (navigator.appName == "Netscape") {
padding = -5
}
obj.style.display = "block"
obj.style.left = orig.offsetLeft
obj.style.top = orig.offsetTop + orig.offsetHeight - padding
obj.onmouseover = function() {
obj.style.display = "block"
}
obj.onmouseout = function(e) {
var ev = event || e
document.onmousemove = function() {
if (ev.clientY > (obj.offsetTop + obj.offsetHeight) + 50) {
obj.style.display = "none"
}
if (ev.clientX < obj.offsetLeft || ev.clientX > (obj.offsetLeft + obj.offsetWidth)) {
obj.style.display = "none"
}
}
}
orig.onmouseout = function() {
obj.style.display = "none"
}
}


This will be your HTML document


<html>
<head>
<style type="text/css">
.menuheader {
display:inline;
margin:0px
}
.menuheader a {
padding:7px;
border:1px solid rgb(73,148,205);
font:10px arial;
font-weight:bold;
color:white;
text-decoration:none;
background:url('gradient.png')
}
.menu {
border:1px solid rgb(73,148,205);
background:rgb(238,238,238);
width:177px;
position:absolute;
display:none
}
.menu a {
color:rgb(52,102,153);
text-decoration:none;
display:block;
font:12px arial;
padding-left:4px;
padding-right:4px;
padding-top:2px;
padding-bottom:2px
}
.menu a:hover {
background:rgb(52,102,153);
color:white
}
</style>
<script type="text/javascript" src="menu.js"></script>
</head>
<body>
<div class="menuheader" onmouseover="showmenu(this,'news')">
<a href="#">NEWS</a>
</div>
<div class="menu" id="news">
<a href="#">Main</a>
<a href="#">Companies</a>
<a href="#">Economies</a>
<a href="#">World Business</a>
<a href="#">News Makers</a>
<a href="#">Fun Money</a>
<a href="#">Corrections</a>
</div>
<div class="menuheader" onmouseover="showmenu(this,'news2')">
<a href="#">NEWS 2</a>
</div>
<div class="menu" id="news2">
<a href="#">Main</a>
<a href="#">Companies</a>
<a href="#">Economies</a>
<a href="#">World Business</a>
<a href="#">News Makers</a>
<a href="#">Fun Money</a>
<a href="#">Corrections</a>
</div>
</body>
</html>

Make a division for the header:

<div class="menuheader" onmouseover="showmenu(this,'newmenu')">BLAH</div>

The second parameter is the menu's id. Make the menu using a div again, and give it links:


<div class="menu" id="newmenu">
<a href="#">Site 1</a>
<a href="#">Site 2</a>
<a href="#">Etc.</a>
</div>

You have to save this image:
http://mburt.mb.funpic.org/test/gradient.png

kamakazi
09-29-2006, 03:35 PM
Thank you so much. I really appriciate your help. I will try it right away.

Thanks again.

mburt
09-29-2006, 03:38 PM
It seems to be malfunctioning in FF... I'll work it out.

mburt
09-29-2006, 03:41 PM
Okay. It's fixed. It should work.

kamakazi
09-29-2006, 03:57 PM
It is not multi level. I tried to add the 3rd level but the positioning is wrong and on mouse out it doesn't close the parent. I tried to do the cnnfn.com and I got the same problem. I can only show the second level properly.

-Thanks

mburt
09-29-2006, 04:00 PM
I'll make a different function for a third-level. Is that okay?

kamakazi
09-29-2006, 04:22 PM
Yes, that's okay. Just to double check that I am doing it right, this how I have added the third level

<table border="0">
<tr>
<td class="menuheader"><div onmouseover="showmenu(this,'news')"><a href="#" >MENU 1</a></div></td>
<td class="menuheader"><div onmouseover="showmenu(this,'news2')"><a href="#">MENU 2</a></div></td>
<td></td>
</tr>
</table>

<div class="menu" id="news">
<a href="#">Button 1</a>
<a href="#">Button 2</a>
<a href="#">Button 3</a>
<a href="#">Button 4</a>
<a href="#">Button 5</a>
</div>
<div class="menu" id="news2">
<a href="#">Button 1</a>
<a href="#">Button 2</a>
<a href="#">Button 3</a>
<a href="#">Button 4</a>
<a href="#">Button 5</a>
<div onmouseover="showmenu(this,'news3')"> <a href="#">Button 7</a> </div>
<a href="#">Button 10</a>
<a href="#">Button 11</a>
</div>
<div class="menu" id="news3">
<a href="#">Button 1</a>
<a href="#">Button 2</a>
<a href="#">Button 3</a>
<a href="#">Button 4</a>
<a href="#">Button 5</a>
<a href="#">Button 7</a>
<a href="#">Button 8</a>
<a href="#">Button 9</a>
</div>

mburt
09-29-2006, 04:30 PM
That doesn't seem to be working very well. I have the second function almost finished. Just wait a minute :)

mburt
09-29-2006, 04:41 PM
Okay. It's done:
The new function is called level(). It has three parameters. The first one is always "this" the second one is the id of the new menu, and the third one is the id of the menu it's coming from.

<html>
<head>
<style>/*<body></body><a href="index.php">Home</a><br><div></div><span></span>/*</style>
<style type="text/css">
.menuheader {
display:inline;
margin:0px
}
.menuheader a {
padding:7px;
border:1px solid rgb(73,148,205);
font:10px arial;
font-weight:bold;
color:white;
text-decoration:none;
background:url('gradient.png')
}
.menu {
border:1px solid rgb(73,148,205);
background:rgb(238,238,238);
width:177px;
position:absolute;
display:none
}
.menu a {
color:rgb(52,102,153);
text-decoration:none;
display:block;
font:12px arial;
padding-left:4px;
padding-right:4px;
padding-top:2px;
padding-bottom:2px
}
.menu a:hover {
background:rgb(52,102,153);
color:white
}
</style>
<script type="text/javascript">
function showmenu(orig,elem) {
var obj = document.getElementById(elem)
var padding = 1
if (navigator.appName == "Netscape") {
padding = -7
}
obj.style.display = "block"
obj.style.left = orig.offsetLeft
obj.style.top = orig.offsetTop + orig.offsetHeight - padding
obj.onmouseover = function() {
obj.style.display = "block"
}
obj.onmouseout = function() {
document.onmousemove = function(e) {
var ev = e || event
if (ev.clientY > (obj.offsetTop + obj.offsetHeight) + 50) {
obj.style.display = "none"
}
if (ev.clientX < obj.offsetLeft || ev.clientX > (obj.offsetLeft + obj.offsetWidth) + 4) {
document.onmousemove = null
obj.style.display = "none"
}
if (ev.clientX > orig.offsetLeft + orig.offsetWidth && ev.clientY < obj.offsetTop) {
obj.style.display = "none"
}
}
}
orig.onmouseout = function() {
obj.style.display = "none"
}
}
function level(orig,elem,origMenu) {
var obj = document.getElementById(elem)
var obj2 = document.getElementById(origMenu)
var padding = 16
var leftpadding = 65
var wid = "100%"
if (navigator.appName == "Netscape") {
padding = 9
leftpadding = 62
wid = ""
}
obj.style.top = (orig.offsetTop + orig.offsetHeight) + obj2.offsetTop - 20
obj.style.left = (orig.offsetLeft + orig.offsetWidth) + obj2.offsetLeft
obj.style.display = "block"
orig.style.width = wid
obj2.onmouseout = function() {
document.onmousemove = function(e) {
var ev = e || event
if (ev.clientX > orig.offsetLeft + orig.offsetWidth) {
obj2.style.display = "block"
document.onmousemove = null
obj.onmouseover = function() {
obj.style.display = "block"
obj2.style.display = "block"
}
obj.onmouseout = function() {
obj.style.display = "none"
obj2.style.display = "none"
}
}
}
}
orig.onmouseout = function() {
obj.style.display = "none"
}
orig.onmouseover = function() {
obj2.style.display = "block"
obj.style.display = "block"
}
}
</script>
</head>
<body>
<div class="menuheader" onmouseover="showmenu(this,'menu1')"><a href="#" style="border-right:none">MENU 1</a></div><div class="menuheader" onmouseover="showmenu(this,'menu2')"><a href="#">MENU 2</a></div>
<div class="menu" id="menu1">
<a href="#">Button 1</a>
<a href="#">Button 2</a>
<a href="#">Button 3</a>
<a href="#">Button 4</a>
<a href="#" onmouseover="level(this,'menu12','menu1')">Button 5 ></a>
</div>
<div class="menu" id="menu2">
<a href="#">Button 1</a>
<a href="#">Button 2</a>
<a href="#">Button 3</a>
<a href="#">Button 4</a>
<a href="#">Button 5</a>
<a href="#">Button 7</a>
<a href="#" onmouseover="level(this,'menu22','menu2')">Button 8 ></a>
<a href="#">Button 9</a>
</div>
<div class="menu" id="menu22">
<a href="#">Button 1</a>
<a href="#">Button 2</a>
<a href="#">Button 3</a>
<a href="#">Button 4</a>
</div>
<div class="menu" id="menu12">
<a href="#">Button 1</a>
<a href="#">Button 2</a>
<a href="#">Button 3</a>
<a href="#">Button 4</a>
<a href="#">Button 5</a>
</div>
</body>
</html>

kamakazi
09-29-2006, 05:00 PM
Just what the doctor ordered. Thanks it look a okay. I will try it on my stuff and give you feedback. Thanks a million times.

mburt
09-29-2006, 05:01 PM
Sometimes the menu cuts out though (the first-level one) when you mouse-over the second-level menu. I'll try to work it out...

kamakazi
09-29-2006, 05:52 PM
One last question? I am sorry for doing this to you, can I have the first level in a table like so

<table border="0">
<tr>
<td class="menuheader"><div onmouseover="showmenu(this,'news')"><a href="#" >MENU 1</a></div></td>
<td class="menuheader"><div onmouseover="showmenu(this,'news2')"><a href="#">MENU 2</a></div></td>
<td></td>
</tr>
</table>

But the td need to use my own defined style ? I tried to do it but then the menu starts miss behaving.

kamakazi
09-29-2006, 06:16 PM
This is how I was trying to fix the second level on cnnfn. My page is centred and it is 760px width and I used some tricks to get the screen size so i can position the submenus properly. It's only the second level menu that works.




<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>
<head>
<script type="text/javascript">
var disappeardelay=500 //menu disappear speed onMouseout (in miliseconds)
var enableanchorlink=0 //Enable or disable the anchor link when clicked on? (1=e, 0=d)
var hidemenu_onclick=1 //hide menu when user clicks within menu? (1=yes, 0=no)

/////No further editting needed

var ie5=document.all
var ns6=document.getElementById&&!document.all

function getposOffset(what, offsettype){
var totaloffset=(offsettype=="left")? what.offsetLeft : what.offsetTop;
var parentEl=what.offsetParent;
while (parentEl!=null){
totaloffset=(offsettype=="left")? totaloffset+parentEl.offsetLeft : totaloffset+parentEl.offsetTop;
parentEl=parentEl.offsetParent;
}
return totaloffset;
}

function showhide(obj, e, visible, hidden){
if (ie5||ns6)
dropmenuobj.style.left=dropmenuobj.style.top=-500
if (e.type=="click" && obj.visibility==hidden || e.type=="mouseover")
obj.visibility=visible;
else if (e.type=="click")
obj.visibility=hidden;
}

function iecompattest(){
return (document.compatMode && document.compatMode!="BackCompat")? document.documentElement : document.body
}

function clearbrowseredge(obj, whichedge){
var edgeoffset=0
if (whichedge=="rightedge"){
var windowedge=ie5 && !window.opera? iecompattest().scrollLeft+iecompattest().clientWidth-15 : window.pageXOffset+window.innerWidth-15
dropmenuobj.contentmeasure=dropmenuobj.offsetWidth
if (windowedge-dropmenuobj.x < dropmenuobj.contentmeasure)
edgeoffset=dropmenuobj.contentmeasure-obj.offsetWidth
}
else{
var topedge=ie5 && !window.opera? iecompattest().scrollTop : window.pageYOffset
var windowedge=ie5 && !window.opera? iecompattest().scrollTop+iecompattest().clientHeight-15 : window.pageYOffset+window.innerHeight-18
dropmenuobj.contentmeasure=dropmenuobj.offsetHeight
if (windowedge-dropmenuobj.y < dropmenuobj.contentmeasure){ //move up?
edgeoffset=dropmenuobj.contentmeasure+obj.offsetHeight
if ((dropmenuobj.y-topedge)<dropmenuobj.contentmeasure) //up no good either?
edgeoffset=dropmenuobj.y+obj.offsetHeight-topedge
}
}
return edgeoffset
}

function dropdownmenu(obj, e, dropmenuID){
if (window.event) event.cancelBubble=true
else if (e.stopPropagation) e.stopPropagation()
if (typeof dropmenuobj!="undefined") //hide previous menu
dropmenuobj.style.visibility="hidden"
clearhidemenu()
if (ie5||ns6){
obj.onmouseout=delayhidemenu
dropmenuobj=document.getElementById(dropmenuID)
if (hidemenu_onclick) dropmenuobj.onclick=function(){dropmenuobj.style.visibility='hidden'}
dropmenuobj.onmouseover=clearhidemenu
dropmenuobj.onmouseout=ie5? function(){ dynamichide(event)} : function(event){ dynamichide(event)}
showhide(dropmenuobj.style, e, "visible", "hidden")
var xypos = getObjectPosition(obj)

var winsize = getWIndowSize()
var win_width_diff = winsize - 760
var win_menu_offset = 0
if (win_width_diff > 0)
{
win_menu_offset = win_width_diff/2
}

dropmenuobj.x=xypos[0]
dropmenuobj.y=xypos[1]
dropmenuobj.style.left=dropmenuobj.x-win_menu_offset+"px"
dropmenuobj.style.top=dropmenuobj.y-clearbrowseredge(obj, "bottomedge")+obj.offsetHeight+"px"
}
return clickreturnvalue()
}


function getWIndowSize() {
return (document.body.offsetWidth);
}
function clickreturnvalue(){
if ((ie5||ns6) && !enableanchorlink) return false
else return true
}

function contains_ns6(a, b) {
while (b.parentNode)
if ((b = b.parentNode) == a)
return true;
return false;
}

function dynamichide(e){
if (ie5&&!dropmenuobj.contains(e.toElement))
delayhidemenu()
else if (ns6&&e.currentTarget!= e.relatedTarget&& !contains_ns6(e.currentTarget, e.relatedTarget))
delayhidemenu()
}

function delayhidemenu(){
delayhide=setTimeout("dropmenuobj.style.visibility='hidden'",disappeardelay);
cnnAlterAllSelects('visible');
}

function clearhidemenu(){
if (typeof delayhide!="undefined")
{
clearTimeout(delayhide)
cnnAlterAllSelects('hidden');
}
}
function cnnAlterAllSelects(visibility)
{
var allSelectObjs = document.getElementsByTagName('select');
if(allSelectObjs)
{
for(var selectCounter = 0;selectCounter<allSelectObjs.length;selectCounter++)
{
var currentSelectObj = allSelectObjs.item(selectCounter);
currentSelectObj.style.visibility=visibility;
}
}
}

function hideSelect(){
if (document.getElementById("dropdownselect"))
document.getElementById("dropdownselect").style.display = 'none';

}
function showSelect(){
if (document.getElementById("dropdownselect"))
document.getElementById("dropdownselect").style.display = 'block';
}
function dropsubdownmenu(obj, e, dropmenuID){
if (window.event) event.cancelBubble=true
else if (e.stopPropagation) e.stopPropagation()
clearhidemenu()

if (ie5||ns6){
obj.onmouseout=delayhidemenu
dropmenuobj=document.getElementById(dropmenuID)
if (hidemenu_onclick) dropmenuobj.onclick=function(){dropmenuobj.style.visibility='hidden'}
dropmenuobj.onmouseover=clearhidemenu
dropmenuobj.onmouseout=ie5? function(){ dynamichide(event,dropmenuobj)} : function(event){ dynamichide(event,dropmenuobj)}
showhide(dropmenuobj.style, e, "visible", "hidden")
var xypos = getObjectPosition(obj)

var winsize = getWIndowSize()
var win_width_diff = winsize - 760 -100
var win_menu_offset = 0
if (win_width_diff > 0)
{
win_menu_offset = win_width_diff/2
}

dropmenuobj.x=xypos[0]-17
dropmenuobj.y=xypos[1]-18
dropmenuobj.style.left=dropmenuobj.x+win_menu_offset+"px"
dropmenuobj.style.top=dropmenuobj.y-clearbrowseredge(obj, "bottomedge")+obj.offsetHeight+"px"
}
return clickreturnvalue()
}


function getObjectPosition(obj) {

window.re

var x_coord = findPosX(obj);
var y_coord = findPosY(obj);

return [x_coord,y_coord];
}

function findPosX(obj)
{
var curleft = 0;
if(obj.offsetParent)
while(1)
{
curleft += obj.offsetLeft;
if(!obj.offsetParent)
break;
obj = obj.offsetParent;
}
else if(obj.x)
curleft += obj.x;
return curleft;
}
function findPosY(obj)
{
var curtop = 0;
if(obj.offsetParent)
while(1)
{
curtop += obj.offsetTop;
if(!obj.offsetParent)
break;
obj = obj.offsetParent;
}
else if(obj.y)
curtop += obj.y;
return curtop;
}


</script>
<title>Untitled</title>
</head>
<body >

<style type="text/css">
.layout-outer-side-decoration {width: 760px;}
.navlinkcss {font:normal 12px/16px Gill Sans MT;background-color:#dfdef8;border:1px solid #272879;text-decoration:none;width:175; position:absolute;visibility:hidden;z-index:100;}
.navlinkcss a, .navlinkcss a:visited {color:#369;display:block;text-indent:2px;white-space:nowrap;text-decoration:none;}
.navlinkcss a:hover {background-color:#dfdef8;color:#272879;text-decoration:bold;}
</style>
<table summary="" width=760px align="center">
<tr>
<td>
<table cellspacing="0" cellpadding="0" border="0" width="100%" bgcolor="#272879">
<tr>
<td width="auto" class="layout-tab-selected" valign="bottom" align="left"
onmouseover="dropdownmenu(this, event, 'navmenu1')">
<div><a href="/web/commed/home" >test 1</a></div>
</td>
<td width="auto" class="layout-tab" valign="bottom" align="left" >
<div><a href="#" >test2</a></div>
</td>
</tr>
</table>

<span class="navlinkcss" id="navmenu1" >
<a href="#"
class="subfoldericon" onmouseover="dropsubdownmenu(this, event, 'subnavmenu1')">Top nav 1 </a>
<div class="alpha-separator"> </div>
<a href="#"
class="subfoldericon" onmouseover="dropsubdownmenu(this, event, 'subnavmenu2')" >Top nav 2 </a>
<div class="alpha-separator"> </div>
</span>



<span class='navlinkcss' id='subnavmenu1' >
<a href='#'>sub navmenu 1</a>
<div class='alpha-separator'> </div>
<a href='#'>sub nav menu 2</a>
<div class='alpha-separator'> </div>
</span>
<span class='navlinkcss' id='subnavmenu2' >
<a href='#'>sub navmenu 3</a>
<div class='alpha-separator'> </div>
<a href='#'>sub nav menu 4</a>
<div class='alpha-separator'> </div>
</span>

</td>
</tr>
</table>
</body>


</html>

mburt
09-29-2006, 06:43 PM
Please. Do me a favor and DON'T USE TABLES!! It screws with the design. Just use it as I showed you before. And yes, you can edit the style as you want.