You can find a lot examples of JavaScript fade menu, but my goal was to make it short and simple – only 20 lines (if you don’t count comment lines). First JavaScript function will initialize event listeners, while second will recursively change opacity level. It should work in all major browsers.
The initialization process collects all A tags beneath TR with id=”menu”. I choose table, but it can be DIV as well. My first solution used getElementById method in the setTimeout recursive loop. Input parameter was object ID, but I wanted to send object pointer. Input parameter for the setTimeout can be a string or a function. No one said it couldn’t be anonymous function. The trick is – when you place a function within another function, you are able to reference variables from the outer function. Means to reference and resend object pointer to the recursive call.
Menu1 | Menu2 | Menu3 | Menu4 | Menu5 | Menu6 |
// highest opacity level var opHigh = 100, // lowest opacity level // should be the same as initial opacity in the CSS opLow = 20, // functions fadeIn, fadeOut, fade; //register onLoad event with anonymous function window.onload = function () { // collect menu items and attach onMouseOver and onMouseOut events var mi = document.getElementById('menu').getElementsByTagName('a'), i; // loop through all elements and attach event listeners for (i = 0; i < mi.length; i++) { // fade in (positive step) mi[i].onmouseover = fadeIn; // fade out (negative step) mi[i].onmouseout = fadeOut; } }; // mouse pointer entered fadeIn = function (event) { // define link ('A' element) reference in TD var a = event.target || event.srcElement; // send TD reference fade(a.parentNode, opLow, 10); }; // mouse pointer out fadeOut = function (event) { // define link ('A' element) reference in TD var a = event.target || event.srcElement; // send TD reference fade(a.parentNode, opHigh, -10); }; // fade in / fade out TD element fade = function (td, opacity, step) { // set opacity for FF td.style.opacity = opacity / 100; // set opacity for IE td.style.filter = 'alpha(opacity=' + opacity + ')'; // update opacity level opacity += step; // recursive call if opacity is between low and high values // (15ms pause between calls) if (opLow <= opacity && opacity <= opHigh) { setTimeout(function () { fade(td, opacity, step); }, 15); } };
Second problem was with events and nested elements. I attached event listener to the TD element and put a link inside. When mouse goes over a link, link fires onMouseOver event. Event propagates (bubbling) and TD catches event. Consequence was blinking tabs. To remove this unwanted effect, event handler should “understand” who fired event and ignore event coming from the inner element, or attach event listener to the A tag directly. In first case, JavaScript code would grow, so I rearranged CSS and attach event listener to the link. After maximising link area, blink problem has disappeared.
<table> <tr id="menu"> <td><a href="#">Menu1</a></td> <td><a href="#">Menu2</a></td> <td><a href="#">Menu3</a></td> <td><a href="#">Menu4</a></td> <td><a href="#">Menu5</a></td> <td><a href="#">Menu6</a></td> </tr> </table> |
#menu td{ background-color: #79b; width: 80px; height: 25px; text-align: center; opacity: 0.2; filter: alpha(opacity=20); } #menu td a{ display: block; width: 100%; height: 100%; line-height: 22px; color: white; } #menu td a:hover{ text-decoration: none; } |
Muito bom o codigo
Utilisei para dar fade em imagens
so que no Mac ele nao sobrepom o texto tal como no PC
gostaria de saber se teria como fazer sobreponha o texto no Mac
Obrigado…
@Alberto – I’m sorry but as I can barely understand you have problem with fade menu on Mac … Unfortunately I do not have Mac near to me to test JavaScript fade menu. Hope that someone can help solving problem you mention.