Click to See Complete Forum and Search --> : [RESOLVED] Moveable Menu Problem.


Mr Initial Man
04-30-2007, 12:04 AM
Below is my layout:


T = Top
M = Menu
C = Content
--L-- Javascript-triggering link
--L-- Clicked javascript-triggering link



What I want to do is to be able to click one of the triggering links and have the menus move down to that link.

+---------+
| T |
+-+-----+-+
|M| |M|
|M| |M|
|M| C |M|
| | | |
| |--L--| |
| | | |
| | C | |
| | | |
| | | |
| | | |
| |--L--| |
| | | |
| | | |
+-+-----+-+


One link clicked

+---------+
| T |
+-+-----+-+
| | | |
| | | |
| | C | |
| | | |
|M|--L--|M|
|M| |M|
|M| C |M|
| | | |
| | | |
| | | |
| |--L--| |
| | | |
| | | |
+-+-----+-+


Another link clicked
+---------+
| T |
+-+-----+-+
| | | |
| | | |
| | C | |
| | | |
| |--L--| |
| | | |
| | C | |
| | | |
| | | |
| | | |
|M|--L--|M|
|M| |M|
|M| |M|
+-+-----+-+


I have the following script.


<head>
...
<script type="text/javascript">
function findPos(obj) {
var curtop = 0;
if (obj.offsetParent) {
curtop = obj.offsetTop
while (obj = obj.offsetParent) {
curtop += obj.offsetTop
}
}
return [curtop];
}
function MenuPosition(elm,menu1)
{
var curPos = findPos(elm)
document.getElementById(menu1).style.top=curPos[1];
document.getElementById(menu1).style.left="20px";

}
</script>
...
</head>
<body>
...
<a href="javascript:MenuPosition(this,'MainMenu')" class="top">Menu</a>
...
</body>


Unfortunately, this doesn't seem to work. What am I doing wrong? As far as I know, my HTML is valid.

This is the error that I'm getting:

Error: Error in parsing value for property 'top'. Declaration dropped.
Source File: http://localhost/Pages/Tutorial/internet.shtml
Line: 0

Note: This must work in as many browsers as possible.

theRatWonder
04-30-2007, 12:39 AM
Without getting as far as understanding how the whole thing actually works, I would say your error is probably because:
document.getElementById(menu1).style.top=curPos[1];
your variable curPos[1] will return just a number, when "style.top" needs to take a number followed by "px".
Change the above line to:
document.getElementById(menu1).style.top=curPos[1] + 'px';
Not tested. Hope it helps.

Mr Initial Man
04-30-2007, 12:44 AM
Still same error.

dragle
04-30-2007, 01:24 PM
Hi!

JavaScript arrays are zero-based. Try:

document.getElementById(menu1).style.top=curPos[0] + 'px';

or perhaps more to the point:

...
return curtop;
...
document.getElementById(menu1).style.top=findPos(elm) + 'px';

Good luck!

Mr Initial Man
04-30-2007, 06:37 PM
Well, the menus are moving, but they go to the position of top:0; (I.E. the very top of the page) rather than down to the menu link.

theRatWonder
04-30-2007, 06:45 PM
have you tried alert(curPos[0]) to see what it thinks the value is?
Or alert(document.getElementById(menu1).style.top)
?

Mr Initial Man
04-30-2007, 07:02 PM
alert(document.getElementById(menu1).style.top)

The result is 0px.

theRatWonder
04-30-2007, 07:54 PM
Okay, I actually took five minutes to look at the thing. Your problem is this:
href="javascript:MenuPosition(this,'MainMenu')"
It turns out that the parent object of the "href" attribute is the window object. So "this", instead of being the anchor element, as it was supposed to be, is the window object, so it doesn't have a offsetParent property.

The solution is to call the MenuPosition from "onclick" rather than "href". Then "this" will work properly.

And while you're at it you might as well use a span and use CSS to make it look like a link. This is the "proper" way to do things, because the element is strictly a javascript control, not an anchor.

Here's a working example I got from adapting your code:

<html>
<head>
<script type="text/javascript">
<!--
function findPos(obj) {
var curtop = 0;
if (obj.offsetParent) {
curtop = obj.offsetTop;
while (obj = obj.offsetParent) {
curtop += obj.offsetTop;
}
}
return [curtop];
}

function MenuPosition(elm,menuId) {
var curPos = findPos(elm);
var menu = document.getElementById(menuId);
menu.style.top = curPos[0] + 'px';
menu.style.left = "20px";
}
//-->
</script>
<style type="text/css">
<!--
#theElem {
position: absolute;
top: 500px;
left: 150px;
cursor: pointer;
text-decoration: underline;
color: blue;
}
#MainMenu {
position: absolute;
}
-->
</style>
</head>
<body>
<span onclick="MenuPosition(this,'MainMenu')" class="top" id="theElem">Menu</span>
<div id="MainMenu">my menu object...</div>
</body>
</html>

Mr Initial Man
04-30-2007, 10:48 PM
Works beautiful!

What I ended up with is:

Javascript
function findPos(obj) {
var curtop = 0;
if (obj.offsetParent) {
curtop = obj.offsetTop
while (obj = obj.offsetParent) {
curtop += obj.offsetTop
}
}
return [curtop];
}
function MenuPosition(elm,menu1,menu2)
{
var curPos = findPos(elm)
document.getElementById(menu1).style.top=curPos[0] + "px";
document.getElementById(menu1).style.left="20px";

document.getElementById(menu2).style.top=curPos[0] + "px";
document.getElementById(menu2).style.right="20px";
}
function MenuReturn(menu1,menu2)
{
document.getElementById(menu1).style.top="140px";
document.getElementById(menu1).style.left="20px";

document.getElementById(menu2).style.top="140px";
document.getElementById(menu2).style.right="20px";

}

HTML
<div class="menuscripts">
<a onclick="MenuPosition(this,'MainMenu','TutorialMenu')" >View Menus</a>
<a onclick="MenuReturn('MainMenu','TutorialMenu')" href="./Basics/markup.shtml#Top" class="toplink">Back To The Top</a>
</div>


CSS
/* ---------- Menu Divisions ---------- */

.menu{
width:200px;
height:500px;
border:1px solid black;
margin:0;
padding:0;
top:140px;
}
.menu li{
margin:5px 0 5px 10px;
padding:0;
list-style-type:none;
width:180px;
}
.menu li.label{
margin:10px;
font-size:150%;
text-decoration:underline;
text-align:center;
}
#MainMenu{
left:20px;
}
#TutorialMenu{
right:20px;
}

/* ---------- Menu Moving ---------- */
div.menuscripts{
border-width:1px;
border-color:gray;
border-style:dotted;
padding:3px;
margin-top:20px;
cursor:pointer;
color:blue;
text-decoration:underline;
text-align:center;
}
.menuscripts a{
display:block;
}
.menuscripts .toplink{
border-top:1px dotted gray;
}

Thanks, this works EXACTLY as I wanted it to.

theRatWonder
04-30-2007, 10:50 PM
:) so glad to help.