It seems like your question has led to a significant amount of research! Allow me to present my findings. I have optimized the solution in a jQuery plugin style, which includes some additional code for flexibility and reusability across your project. You also have the option to set fadeIn
to false
, causing it to fade out in a similar fashion:
<!DOCTYPE html >
<html>
<head>
<style type="text/css" media="screen">
#items { height:50px; text-align: center; line-height: 50px; }
#items div {
width: 50px; height: 50px;
float: left; position: relative;
background: red;
opacity: 0.0; -moz-opacity: 0.0; filter:alpha(opacity=0);
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript" charset="utf-8">
$.fn.fadeFromOutside = function(opts){
if(this.size() > 0){
var options = options = $.extend({}, $.fn.fadeFromOutside.defaults, opts),
size = this.size(),
steps = Math.ceil(size / 2), // Always round up
fade_in = options.fadeIn,
time = options.length,
wait = Math.floor(time / steps), // Delay between fades
items = this.css({opacity: (fade_in ? 0.0 : 1.0)}),
fade_to = (fade_in ? 1.0 : 0.0); // Decide final opacity
// Using private internal function for processing and delayed fadeIn.
var fade_action = function(one, two, count_left, delay){
var callback = null;
if( options.complete && count_left == (steps - 1))
callback = options.complete;
$(one).animate({opacity: fade_to}, {duration: time, complete: callback});
if(one != two)
$(two).animate({opacity: fade_to}, time);
if(count_left < steps){
window.setTimeout(function(){
fade_action(
items.get(count_left),
items.get(size - 1 - count_left),
count_left + 1,
delay);
}, delay);
}
}
// Initiate the fade
fade_action(items.get(0), items.get(size - 1), 1, wait);
}
return this; // Maintain chain
}
$.fn.fadeFromOutside.defaults = {
fadeIn: true,
length: 1000
}
/* DOM Ready */
$(function(){
$("#items > div").fadeFromOutside({
fadeIn: true,
length: 2000,
complete: function(){
alert('done!');
}
});
});
</script>
</head>
<body>
<div id="items">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
</div>
</body>
</html>
If the elements initially have display:none
or require fading out to end with display:none
, use the following command to trigger the plugin:
// For fadeIn when divs start as display:none
$("#items > div")
.css({display: block, opacity: 0.0})
.fadeFromOutside();
// For fadeOut to hide all divs at the end
$("#items > div")
.fadeFromOutside({
complete: function(){ $("#items > div").hide() }
});
});