Fade an Element

This script is useful for adding a little visual interest to pages by animating a fade in/out effect. You can pass as many individual objects to it as you like and the animation is handled by a single setInterval function. The entire code is wrapped up in a portable library object.

Step One: The fadeElement object

This is the outline of the fadeElement library object:

var fadeElement = { initialise: function() {}, setOpacity: function() {}, fader: function() {}, objArray: [] }

A simple outline showing three methods and one property. It's quite easy to tell from the name of each what its role is.

Step Two: The initialise method

The initialise method does exactly what it says on the tin. It sets up each object passed to the script for interaction with the other methods. Here's the method's code in full:

initialise: function(obj) { fadeElement.setOpacity(obj, 20); fadeElement.objArray.push(obj); obj.fadeState = ''; obj.onmouseover = function() { this.fadeState = 'fadingIn'; } obj.onmouseout = function() { this.fadeState = 'fadingOut'; } if (!window.fadeTimer) window.fadeTimer = setInterval(fadeElement.fader, 50); },

The function accepts the argument obj which stands for the document element passed into the script. This object is then passed to the setOpacity method and also added to the objArray property to keep a permanent record of it. After this, a fadeState property is given to the object but is currently unset. Event handlers for mouseover and mouseout are added with anonymous functions that update the fadeState property accordingly. If the mouse pointer moves over the object, the fadeState becomes 'fadingIn' and if the pointer moves off it becomes 'fadingOut'.

Lastly, the code checks to see if the window object already has a fadeTimer object attached and, if not, attaches one. The fadeTimer calls the fader method every 50 milliseconds.

Step Three: The setOpacity method

As far as methods go this one is about as simple as it gets:

setOpacity: function(obj, opacity) { obj.style.filter = "alpha(opacity=" + opacity + ")"; // For IE filter to work, obj MUST have layout obj.style.KHTMLOpacity = opacity / 100; // Safari and Konqueror obj.style.MozOpacity = opacity / 100; // Old Mozilla and Firefox obj.style.opacity = opacity / 100; // CSS3 opacity for browsers that support it },

Fulfilling just a single purpose, this method applies the passed opacity value to the passed object. The only reason it takes four lines of code to do this instead of one is because of differences in the way browsers handle an element's opacity setting.

The last line is the only 'correct' way to set opacity according to the standards set out by the W3C but very few browsers currently support it. For this reason the script has to take advantage of proprietary code to achieve consistency across a wide range of user agents. What a pain.

Incidentally, for an explanation of what I mean in the first comment about the element requiring 'layout', check out Microsoft's own documentation on this issue.

Step Four: The fader method

If fadeElement could be said to have a heart then this method would be it. Thanks to the window.fadeTimer established in the initialise method, fader is called every 50 milliseconds and executes the following code:

fader: function() { for (var i = 0; i < fadeElement.objArray.length; i++) { var opacity = fadeElement.objArray[i].style.opacity * 100; if (fadeElement.objArray[i].fadeState == 'fadingIn' && opacity < 100) fadeElement.setOpacity(fadeElement.objArray[i], opacity + 10); else if (fadeElement.objArray[i].fadeState == 'fadingOut' && opacity > 20) fadeElement.setOpacity(fadeElement.objArray[i], opacity - 10); } },

Remember how the object was pushed into objArray during the execution of initialise? That allows fader to access that object and any others passed into the script by looping through the array. As each object occurs in the loop, it's opacity value is read and given to the variable opacity.

Using an if/else conditional statement, fader checks the fadeState property of the object. If the object is marked as fading in and the current opacity of the object is less than 100, the script increases opacity by 10 and sends both the object and the new opacity value to setOpacity. If the object is fading out then the process is repeated but this time the script checks if the opacity is greater than 50 and subtracts 10 if this proves to be the case.

Step Five: The Completed Script

All in all, this is a nice and easy to implement effect, and here is the completed script in full:

var fadeElement = { initialise: function(obj) { fadeElement.setOpacity(obj, 20); fadeElement.objArray.push(obj); obj.fadeState = ''; obj.onmouseover = function() { this.fadeState = 'fadingIn'; } obj.onmouseout = function() { this.fadeState = 'fadingOut'; } if (!window.fadeTimer) window.fadeTimer = setInterval(fadeElement.fader, 50); }, setOpacity: function(obj, opacity) { obj.style.filter = "alpha(opacity=" + opacity + ")"; // For IE filter to work, obj MUST have layout obj.style.KHTMLOpacity = opacity / 100; // Safari and Konqueror obj.style.MozOpacity = opacity / 100; // Old Mozilla and Firefox obj.style.opacity = opacity / 100; // CSS3 opacity for browsers that support it }, fader: function() { for (var i = 0; i < fadeElement.objArray.length; i++) { var opacity = fadeElement.objArray[i].style.opacity * 100; if (fadeElement.objArray[i].fadeState == 'fadingIn' && opacity < 100) fadeElement.setOpacity(fadeElement.objArray[i], opacity + 10); else if (fadeElement.objArray[i].fadeState == 'fadingOut' && opacity > 20) fadeElement.setOpacity(fadeElement.objArray[i], opacity - 10); } }, objArray: [] }

I have also posted a working example.

2005-12-31

© 2005 - 2024 Iain Gardiner. All rights reserved.