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