 |
| Javascript General Javascript discussions. |
Welcome to the p2p.wrox.com Forums.
You are currently viewing the Javascript section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
|
|
|
|

September 26th, 2003, 01:58 AM
|
 |
Wrox Author
|
|
Join Date: Jun 2003
Posts: 1,706
Thanks: 0
Thanked 6 Times in 6 Posts
|
|
Dynamic Link Menus
Hello,
I am pretty *green* when it comes to JavaScript. I have been working on the dynamic link menu example in chapter 12 of the Beginning JavaScript book. I understand programming concepts really well.. I'm a PHP programmer by trade.
What I am trying to do with the code is convert the example that takes an image object and takes the image's position and adds its width and then repositions a <div> element that onload is positioned off screen to the right of the image creating that dynamic link menu effect. I want to take this code and rewrite it so that the source element doesn't have to be an image, but rather plain text or a div.
I would like to do something that doesn't rely on the source element as being absolutely positioned while maintaining the ambiguity of the code so that it can be reused in other projects. For now cross-browser compatibility doesn't matter to me. I use IE6.
For the sake of learning I would grately appreciate someone walking me through the js objects and code required to create this ambiguity... rather than simply fixing my code.
Thanks in advance!
: )
Rich
Code:
<html>
<head>
<style type='text/css'>
.divMenu {
position: absolute;
left: -200px;
top: -1000px;
width: 180px;
z-index: 100;
background-color: blue;
border: 1px solid black;
}
.tdMenu {
color: white;
font-family: sans;
font-size: 12pt;
width: 100%;
cursor: default;
}
</style>
<script language='JavaScript' type='text/javascript'>
/*
* Example using image elements as source object
*
*/
function show_menu(menu)
{
var srcElement = event.srcElement;
var x = parseInt(srcElement.offsetLeft);
var y = parseInt(srcElement.offsetTop);
menu.style.left = x + (srcElement.width);
menu.style.top = y;
}
function hide_menu(menu)
{
if (event.toElement != menu && menu.contains(event.toElement) == false)
{
menu.style.left = -200;
menu.style.top = -1000;
}
}
/*
* Example using div or text elements as source object
*
*/
function show_menu_(menu)
{
var srcElement = event.srcElement;
var x = parseInt(srcElement.style.left);
var y = parseInt(srcElement.style.top);
// This code does not work as expected! menu.style.left appears 2000 or 3000 pixels to the right!
menu.style.left = x + (srcElement.style.width);
menu.style.top = y;
}
function hide_menu_(menu)
{
if (event.toElement != menu && menu.contains(event.toElement) == false)
{
menu.style.left = -200;
menu.style.top = -1000;
}
}
function goto_page(url)
{
window.location.href = url;
}
</script>
</head>
<body>
<div id='divText' class='divMenu' onmouseout='return hide_menu(this)'>
<table>
<tr>
<td id='tdText' RollOver='' RollOut='' class='tdMenu'>
some text<br />
some more text
</td>
</tr>
</table>
</div>
<img src='images/blue_background.jpg' id='thisImage' style='position: absolute; left: 10px; top: 75px; z-index: 1;' onmouseover='show_menu(divText)' onmouseout='hide_menu(divText)' />
<div style='position: absolute; left: 10px; top: 100px; z-index: 1; width: 100px;' onmouseover='show_menu_(divText)' onmouseout='hide_menu_(divText)'>
test
</div>
</body>
</html>
:::::::::::::::::::::::::::::::::
Smiling Souls
http://www.smilingsouls.net
:::::::::::::::::::::::::::::::::
|
|

September 26th, 2003, 03:27 AM
|
|
Friend of Wrox
|
|
Join Date: Jun 2003
Posts: 1,212
Thanks: 0
Thanked 1 Time in 1 Post
|
|
Hi Rich,
I don't see anything there that is specific to an image.
The reason your code isn't working is coz in this line:
// This code does not work as expected! menu.style.left appears 2000 or 3000 pixels to the right!
menu.style.left = x + (srcElement.style.width);
the expression srcElement.style.width return the string 100px, so you think you're adding 10 to 100,
but actually you're getting string concatenation, i.e. menu.style.left gets the value 10100px !
The original show_menu uses the offsetLeft property, not the style.left property.
However, there is a problem with relying on offsetLeft because you'll find that it
represents the offset from its parent - so if you put the element in a table it all screws up.
Take a look at this previous post regarding exactly that subject:
http://p2p.wrox.com/topic.asp?TOPIC_ID=3419
hth
Phil
|
|

September 26th, 2003, 02:27 PM
|
 |
Wrox Author
|
|
Join Date: Jun 2003
Posts: 1,706
Thanks: 0
Thanked 6 Times in 6 Posts
|
|
Thanks Phil,
That post was very helpful. I still can't get it to work with a div that calls an onmouseover event (instead of an image).
I used the example in the post:
Code:
function show_menu(menu)
{
var srcElement = event.srcElement;
var x;
var y;
if (srcElement)
{
x = srcElement.width;
y = 0;
}
while (srcElement)
{
x += srcElement.offsetLeft;
y += srcElement.offsetTop;
srcElement = srcElement.offsetParent;
}
menu.style.top = y;
menu.style.left = x;
}
<img src='images/blue_background.jpg' id='thisImage' style='position: absolute; left: 10px; top: 75px; z-index: 1;' onmouseover='show_menu(divText)' onmouseout='hide_menu(divText)' />
<div style='position: absolute; left: 10px; top: 100px; z-index: 1; width: 100px;' onmouseover='show_menu(divText)' onmouseout='hide_menu(divText)'>
test
</div>
Would I need to include the parseInt() function? How would I add a number and a string in JavaScript? In PHP, PHP automatically extracts the integer from the string and treats it as an integer with respect to mathematical operations - ignoring everything but the integer content of the string. Is there a method in JavaScript that will do the same? I use the 'px' for standards compliance. Mostly because Navigator has no default measurement mechanism and when the unit of measurement is left off it causes the browser to not display or render certain CSS elements.
Thanks Again,
Rich
:::::::::::::::::::::::::::::::::
Smiling Souls
http://www.smilingsouls.net
:::::::::::::::::::::::::::::::::
|
|

September 26th, 2003, 05:23 PM
|
 |
Wrox Author
|
|
Join Date: Jun 2003
Posts: 1,706
Thanks: 0
Thanked 6 Times in 6 Posts
|
|
Hello again,
I was able to answer many of my own questions with a bit of research. The culprit it seems was the call to x = srcElement.width; when the value of 'x' was output it contained a 'NaN' value. The following is what I did to get around it.
Code:
function show_menu(menu)
{
// parseInt() - Extract only the integer value
// If the srcElement.width object does not contain a numeric value
// Use the srcElement.style.width object, which must be defined
var srcElement = event.srcElement;
var x;
var y;
if (srcElement)
{
x = parseInt(srcElement.width);
if (isNaN(x))
{
x = parseInt(srcElement.style.width);
}
y = 0;
}
while (srcElement)
{
x += parseInt(srcElement.offsetLeft);
y += parseInt(srcElement.offsetTop);
srcElement = srcElement.offsetParent;
}
if (isNaN(x))
{
output(x);
}
menu.style.top = y + 'px';
menu.style.left = x + 'px';
}
function output(object)
{
document.write('<br />' + object + '<br />');
}
Is there any other object that I could use, besides the 'srcElement.style.width' that would give me that value? Am I correct in deducing that value must be explicitly defined in the HTML source?
Thanks again for your insight!
: )
Rich
:::::::::::::::::::::::::::::::::
Smiling Souls
http://www.smilingsouls.net
:::::::::::::::::::::::::::::::::
|
|

September 29th, 2003, 03:33 AM
|
|
Friend of Wrox
|
|
Join Date: Jun 2003
Posts: 1,212
Thanks: 0
Thanked 1 Time in 1 Post
|
|
Quote:
quote:Originally posted by quesadilla5
Hello again,
I was able to answer many of my own questions with a bit of research. The culprit it seems was the call to x = srcElement.width; when the value of 'x' was output it contained a 'NaN' value. The following is what I did to get around it.
...
Is there any other object that I could use, besides the 'srcElement.style.width' that would give me that value? Am I correct in deducing that value must be explicitly defined in the HTML source?
Thanks again for your insight!
: )
Rich
:::::::::::::::::::::::::::::::::
Smiling Souls
http://www.smilingsouls.net
:::::::::::::::::::::::::::::::::
|
Ah, of course, now I see your problem on using divs instead of images - images (nearly) always have a width attribute defined, but divs do not. Sorry, that should have clicked before.
Ok, the style property exposes inline style statements, e.g. width, so if you don't specify the width then all you get is an empty string.
(You've already noticed, no doubt, that div element does not have an HTML width attribute defined). Also, I'm pretty sure that the style property only exposes inline styles, so any inherited styles, or styles from external CSS don't get picked up. IE exposes a currentStyle property which picks up a lot more of these.
For a div I think the most reliable property to use would be the offsetWidth (that's divName.offsetWidth, not divName.style.offsetWidth) because that will give you the width whether or not it has been explicitly specified by a CSS style (although, for your example, you would always want to specify the width otherwise the div takes up the entire browser width since it is a block element).
hth
Phil
|
|

September 29th, 2003, 03:55 AM
|
|
Friend of Wrox
|
|
Join Date: Jun 2003
Posts: 1,212
Thanks: 0
Thanked 1 Time in 1 Post
|
|
Hi Rich,
Just had another thought on this. There was a recent post that talked about getting the width of the actual text in a div or span object, and I thought that you might get you a nicer looking result if you didn't specify the actual width of the div, but instead just used the width of the actual text to position the menu. The topic link is here http://p2p.wrox.com/topic.asp?TOPIC_ID=3794, however, it doesn't work nicely for divs (presumably because they are block elements), but it does work well for <span> elements (presumably because they are in-line elements). So maybe you might ant to try using <span> instead of <div>.
rgds
Phil
|
|

September 29th, 2003, 11:58 PM
|
 |
Wrox Author
|
|
Join Date: Jun 2003
Posts: 1,706
Thanks: 0
Thanked 6 Times in 6 Posts
|
|
Hi Phil!
The offsetWidth did the trick. Although it ended up being:
document.getElementById(tdid).offsetWidth;
and not
srcElement.offsetWidth;
As mentioned in the second post you directed me to. Works beautifully! Thanks for the insight.
For anyone interested, the following is what I ended up with, which works for images or inlines. I have yet to write compatibility code for NS/Mozilla so this only works in IE.
Code:
/*
* Dynamically reposition an element
* void show_menu(string id to reposition, string id of source element)
*/
function show_menu(menu, tdid)
{
// parseInt() - Extract only the integer value
// If the srcElement.width object does not contain a numeric value
// Use the offsetWidth property instead
// if the offestWidth property does not contain a numeric value
// Use the srcElement.style.width property instead, which must be defined explicitly
var srcElement = event.srcElement;
var x;
var y = 0;
if (srcElement)
{
x = parseInt(srcElement.width);
if (isNaN(x))
{
x = parseInt(document.getElementById(tdid).offsetWidth);
if (isNaN(x))
{
x = parseInt(srcElement.style.width);
}
}
}
if (isNaN(x))
{
alert('Error: x is NaN');
}
while (srcElement)
{
x += parseInt(srcElement.offsetLeft);
y += parseInt(srcElement.offsetTop);
srcElement = srcElement.offsetParent;
}
// shift x slightly to the left
x = x - 5;
document.getElementById(menu).style.top = y + 'px';
document.getElementById(menu).style.left = x + 'px';
}
: )
Rich
:::::::::::::::::::::::::::::::::
Smiling Souls
http://www.smilingsouls.net
:::::::::::::::::::::::::::::::::
|
|

July 7th, 2004, 02:25 PM
|
|
Authorized User
|
|
Join Date: Jun 2003
Posts: 83
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
of course, there are simpler ways to make a popup menu.
http://www.meyerweb.com/eric/css/edge/menus/demo.html
describes a way to make css popup menus that work with non-IE browsers. now if you want IE compatibility, you can easily add some simple java scripts to change the style.display from none to block so everything functions properly.
There methods are much more simple, which provides faster loadtime for the page, easier updates, and faster run-time efficiency, not to mention forwards compatibility.
----------------------------
Aeon of Darkness MUD - Free Online Roleplaying Game
http://aeonofdarkness.com
|
|

July 7th, 2004, 05:23 PM
|
 |
Wrox Author
|
|
Join Date: Jun 2003
Posts: 1,706
Thanks: 0
Thanked 6 Times in 6 Posts
|
|
This thread is pretty *old*.. but I'll answer myself for new people that find it ;).
It is possible to do menus with no javascript at all in all of the major browsers, IE, Gecko, Opera, Safari.. etc. with pure CSS.
See: http://dean.edwards.name/IE7
This URL offers a collection of IE behaviours that make meyer's pure CSS menus example work flawlessly in IE 6.
Regards,
Rich
::::::::::::::::::::::::::::::::::::::::::
The Spicy Peanut Project
http://www.spicypeanut.net
::::::::::::::::::::::::::::::::::::::::::
|
|
 |