473,504 Members | 13,621 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Changing the background color of menu items based on mouse proximity.

59 New Member
I'm not sure if this is possible, but I thought I saw it somewhere and I'd like to know how to do it.

This is rather difficult to explain, so bare with me.

Lets say you have 3 background colors, going from lightest to darkest (so color 1 would be the lightest and color 3 would be the darkest).

I'll try to illustrate what I mean. Let's say the mouse is over Item 4.

Item 1 - color 3
Item 2 - color 3
Item 3 - color 2
Item 4 - color 1
Item 5 - color 2
Item 6 - color 3

Let's say the mouse isn't over any of them.


Item 1 - color 3
Item 2 - color 3
Item 3 - color 3
Item 4 - color 3
Item 5 - color 3
Item 6 - color 3

Basically I want it so when the mouse is over an item, that item fades to have the lightest background, and the items next it have darker backgrounds, and the other items have the darkest background.

I hope this is clear enough and I hope someone can help me with this. Thanks to anyone who helps :)
Aug 21 '07 #1
8 2307
pbmods
5,821 Recognized Expert Expert
Heya, metaphysics.

Ooh neat idea.

First off, I'll go ahead and change the thread title to better describe the problem (did you know that threads whose titles that do not follow the Posting Guidelines actually get FEWER responses?).

Now then, think about it this way: The color depends on the distance (in menu items) from the mouse, with a maximum of 2. In other words:

Item 1 - 3 away from mouse > 2, so use 2 instead -> color 0 + 2 = 2
Item 2 - 2 away from mouse <= 2 -> color 0 + 2 = 2
Item 3 - 1 away from mouse < 2 -> color 0 + 1 = 1
Item 4 - Under mouse (0 < 2) -> color 0 + 0 = 0
Item 5 - 1 away from mouse < 2 -> color 0 + 1 = 1
Item 6 - 2 away from mouse <= 2 -> color 0 + 2 = 2

Ok, say what? So you have your list of colors:
Expand|Select|Wrap|Line Numbers
  1. var colors = [
  2.     '#3333ff',        // Color 0
  3.     '#3333cc',        // Color 1
  4.     '#333399'        // Color 2
  5. ];
  6.  
Now all you have to do is determine your 'distance':
Expand|Select|Wrap|Line Numbers
  1. <li id="menu_1" onmouseover="setColors(this);">Item 1</li>
  2. <li id="menu_2" onmouseover="setColors(this);">Item 2</li>
  3. .
  4. .
  5. .
  6. <script type="text/javascript">
  7.     // <![CDATA[
  8.     function setColors(hovered)
  9.     {
  10.         var target = parseint(hovered.id.match(/\d+$/));
  11.         for(var i = 1; var e = document.getElementById('menu_' + i); ++i)
  12.         {
  13.             e.style.backgroundColor = colors[Math.min(Math.abs(i - target), colors.length - 1)];
  14.         }
  15.     }
  16.     // ]]>
  17. </script>
  18.  
As an example, suppose you hovered over menu_4.

setColors would set target = 4.
For each menu item, set the background color equal to one of the elements of the colors array. To determine that color, take the absolute value of the current element's position minus (in this case) 4. If the result is greater than the index of the last color (which in this case is 2), use that value instead.

So if item 4 were hovered:

Item 1 => target = 4, i = 1; abs(1 - 4) = 3 (> 2, use colors[2])
Item 2 => target = 4, i = 2; abs(2 - 4) = 2 (use colors [2])
Item 3 => target = 4, i = 3; abs(3 - 4) = 1 (use colors [1])
Item 4 => target = 4, i = 4; abs(4 - 4) = 0 (use colors [0])
Item 5 => target = 4, i = 5; abs(5 - 4) = 1 (use colors [1])
Item 6 => target = 4, i = 6; abs(6 - 4) = 2 (use colors [2])
Item 7 doesn't exist => break;
Aug 21 '07 #2
metaphysics
59 New Member
I think I'm beginning to follow what you mean, but I have very little javascript knowledge. A few questions:

Lets say I need multiple groups. Do I need to keep the menu number unique? Does it have to be chronological if it needs to be unique? Can different grouped menus be say, menu_1 for group1, menu_2 for group2, etc?

example1 (chronological)
Expand|Select|Wrap|Line Numbers
  1. <li id="menu_1" onmouseover="setColors(this);">Item 1</li>
  2. <li id="menu_2" onmouseover="setColors(this);">Item 2</li>
or can it be

example2 (unique)
Expand|Select|Wrap|Line Numbers
  1. <li id="menu_17" onmouseover="setColors(this);">Item 1</li>
  2. <li id="menu_32" onmouseover="setColors(this);">Item 2</li>
or even

example3 (group1)
Expand|Select|Wrap|Line Numbers
  1. <li id="menu_1" onmouseover="setColors(this);">Item 1</li>
  2. <li id="menu_1" onmouseover="setColors(this);">Item 2</li>

Can the <li> tags be replaced with <div> tags, and how so?

Sorry to ask so many questions. Thank you for the help :)
Aug 23 '07 #3
pbmods
5,821 Recognized Expert Expert
Heya, Metaphysics.

Let's have some fun.

Lets say I need multiple groups. Do I need to keep the menu number unique? Does it have to be chronological if it needs to be unique? Can different grouped menus be say, menu_1 for group1, menu_2 for group2, etc?

example1 (chronological)
Expand|Select|Wrap|Line Numbers
  1. <li id="menu_1" onmouseover="setColors(this);">Item 1</li>
  2. <li id="menu_2" onmouseover="setColors(this);">Item 2</li>
A very basic example, yes.

What you'll probably want to do is add the group to each element's ID. Keep reading.

or can it be

example2 (unique)
Expand|Select|Wrap|Line Numbers
  1. <li id="menu_17" onmouseover="setColors(this);">Item 1</li>
  2. <li id="menu_32" onmouseover="setColors(this);">Item 2</li>
Sort of.

or even

example3 (group1)
Expand|Select|Wrap|Line Numbers
  1. <li id="menu_1" onmouseover="setColors(this);">Item 1</li>
  2. <li id="menu_1" onmouseover="setColors(this);">Item 2</li>
Definitely not. But you have the right idea.

Consider this: Each item in a particular group has to have a sequential ID (menu_1, menu_2, etc.). But you need to use the IDs to differentiate between the different groups. What about something like this:

Expand|Select|Wrap|Line Numbers
  1. <!-- Menu Group 1 -->
  2. <li id="menu_g1_i1" onmouseover="setColors(this);">Item 1</li>
  3. <li id="menu_g1_i2" onmouseover="setColors(this);">Item 2</li>
  4. .
  5. .
  6. .
  7. <!-- Menu Group 2 -->
  8. <li id="menu_g2_i1" onmouseover="setColors(this);">Item A</li>
  9. <li id="menu_g2_i2" onmouseover="setColors(this);">Item B</li>
  10.  
Now then, because we know how the string is formatted ('menu_g' + group number + '_i' + item number), we can easily apply regular expressions to turn the description into real values:

Expand|Select|Wrap|Line Numbers
  1. <script type="text/javascript">
  2.     // <![CDATA[
  3.     function setColors(hovered)
  4.     {
  5.         var targets = hovered.id.match(/menu_g(\d+)_i(\d+)/);
  6.         for(var i = 1; var e = document.getElementById('menu_g' + targets[1] + '_i' + i); ++i)
  7.         {
  8.             e.style.backgroundColor = colors[Math.min(Math.abs(i - targets[2]), colors.length - 1)];
  9.         }
  10.     }
  11.     // ]]>
  12. </script>
  13.  
I'm a little fuzzy on regular expression grouping in JavaScript, but I believe that the syntax above is correct. Note that when setColors() executes, targets becomes an array in a format that might look like this for Item A in the list above:
Expand|Select|Wrap|Line Numbers
  1. var targets = [
  2.     'menu_g2_i1',
  3.     '2',
  4.     '1'
  5. ];
  6.  
Notice that targets[1] is the group number, and targets[2] is the item number. All we have to do is plug those values into the for loop, and we should be good to go.

Can the <li> tags be replaced with <div> tags, and how so?
Sure. document.getElementById() doesn't care, so long as the ID matches.

Sorry to ask so many questions. Thank you for the help :)
Don't worry about it; I'm going for the top 10 :)
Aug 23 '07 #4
metaphysics
59 New Member
Aah. I feel as if I'm testing you at this point :)

Going back to what I mentioned earlier about having unique menu numbers, how would I set it so it could be like this:

Expand|Select|Wrap|Line Numbers
  1. <!-- Menu Group 1 -->
  2. <div id="menu_17" onmouseover="setColors(this);">Item 1</div>
  3. <div id="menu_32" onmouseover="setColors(this);">Item 2</div>
  4.  
  5. <!-- Menu Group 2 -->
  6. <div id="menu_12" onmouseover="setColors(this);">Item 1</div>
  7. <div id="menu_4" onmouseover="setColors(this);">Item 2</div>
  8.  
Edit: uhhh and is it possible that on transition they fade instead of just switching? I don't know the power of javascript, but I figured I'd ask.
Aug 23 '07 #5
pbmods
5,821 Recognized Expert Expert
Heya, metaphysics.

The issue with the IDs that you used is that they are not sequential, so you would have no way of knowing which IDs are next to each other.

If the items have to have those ID numbers, then you have three options (all of which are more intricate than using IDs):
  • You can create two node crawlers. One starts at the currently-hovered node and moves up, coloring nodes until it hits the end of the group. The other starts one down from the currently-hovered node and moves down.
  • You can use the element's parent's getElementsByTagName() method and then traverse through the resulting array. To make this work, each menu group has to be enclosed within a parent node of some kind (such as a div).
  • You can set up a JavaScript array that maps elements to groups. This one's the easiest to execute, but it takes the most work to set up.

Fading is possible, most easily accomplished using the Scriptaculous Effects package, but I'm no good at proprietary stuff, so you might want to ask about that in a separate thread once you get this working.
Aug 23 '07 #6
metaphysics
59 New Member
Alright. I'm having trouble fitting this into a document - what would it look like (the chronological one with groups)?
Aug 23 '07 #7
pbmods
5,821 Recognized Expert Expert
Heya, Metaphysics.

For each group, you would use a separate 'g' number:
Expand|Select|Wrap|Line Numbers
  1. <!-- Menu Group 1 - menu_g1_i# -->
  2. <div id="menu_g1_i1" onmouseover="setColors(this);">Item 1</div>
  3. <div id="menu_g1_i2" onmouseover="setColors(this);">Item 2</div>
  4. .
  5. .
  6. .
  7. <!-- Menu Group 2 - menu_g2_i# -->
  8. <div id="menu_g2_i1" onmouseover="setColors(this);">Item A</div>
  9. <div id="menu_g2_i2" onmouseover="setColors(this);">Item B</div>
  10.  
Then to set the colors:
Expand|Select|Wrap|Line Numbers
  1. <script type="text/javascript">
  2.     // <![CDATA[
  3.     function setColors(hovered)
  4.     {
  5.         var targets = hovered.id.match(/menu_g(\d+)_i(\d+)/);
  6.         for(var i = 1; var e = document.getElementById('menu_g' + targets[1] + '_i' + i); ++i)
  7.         {
  8.             e.style.backgroundColor = colors[Math.min(Math.abs(i - targets[2]), colors.length - 1)];
  9.         }
  10.     }
  11.     // ]]>
  12. </script>
  13.  
Note that the elements themselves don't have to be 'next to each other'. For example:
Expand|Select|Wrap|Line Numbers
  1. <div id="menu_g1_i1" onmouseover="setColors(this);">
  2.     Item 1
  3.     <div id="menu_g101_i1" onmouseover="setColors(this);">Sub-Item 1</div>
  4.     <div id="menu_g101_i2" onmouseover="setColors(this);">Sub-Item 1</div>
  5.     <div id="menu_g101_i3" onmouseover="setColors(this);">Sub-Item 1</div>
  6.     <div id="menu_g101_i4" onmouseover="setColors(this);">Sub-Item 1</div>
  7. </div>
  8. <div id="menu_g1_i2" onmouseover="setColors(this);">Item 2</div>
  9. <div id="menu_g1_i3" onmouseover="setColors(this);">Item 3</div>
  10. <div id="menu_g1_i4" onmouseover="setColors(this);">Item 4</div>
  11.  
When you mouse over any of the elements in the sub-group, setColors() will run both for the main group (all the 'menu_g1' elements) as well as the sub-group (all the 'menu_g101' elements). Note that the 'g' number doesn't really matter as long as each group gets its own unique number and all elements in the same group have the same 'g' number.
Aug 23 '07 #8
metaphysics
59 New Member
Do I need to set any CSS? I'm not sure I understand how the background color is set =/
Aug 23 '07 #9

Sign in to post your reply or Sign up for a free account.

Similar topics

25
4297
by: madsgormlarsen | last post by:
Hi I am making a tab menu with css, and the tabs changes color depending on wich tab is current. 1. I could load a different css file for each tab/color. 2. I could do some inline css only...
0
1435
by: Vidula | last post by:
I am using the menu control in ASP.NET using VS2005. I want to change the background color of the dynamic menu when the mouse hovers over that menu item. This works fine when the background color...
2
5814
by: H | last post by:
is it possible to add a background image to the menu items? I can add an image, but it displays on top of the text of the menu items. How can I add the image and still have the text in the...
8
2090
by: gs | last post by:
I was able to set tooltips on objects other than main menu. I would like to get the effect of tooltip or microhelp in the bottom status bar when the mouse is hovering over a submenu item. How do...
1
2145
by: Anthony | last post by:
Below is a script I found at http://javascript.internet.com/ for a cascading menu. The script works great but there is one thing that I would like modified. BecauseI am just learning javascript,...
0
1034
by: sandeepthoppil | last post by:
Hi I dont know whether I am doing something wrong here. But this is very strange thing I have noted with menu strip control. I am using VB 2005. I am using a menu strip control as the main menu...
1
5241
by: =?Utf-8?B?QW5kcmV3?= | last post by:
Hi, friends, I am using C#.net 2005 to create a windows application. It has menu items, such as File, etc. Under File, there are more menu items, such as New Files, Working Files, etc. Under...
8
1861
by: richard | last post by:
I have <div id=box1 style="display:block"as the initial setting. I need to change the "display:block" to "display:none" then back to "display:block" as a means of clearing anything that might be...
0
7098
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7298
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7366
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
7471
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5610
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
5026
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
4698
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
1526
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
1
754
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.