views:

465

answers:

5

Hi.

I'd like to fade in several boxes aligned horizontally one after the next. Say each box belongs to class fadeable and has an id. Addtionally, I'd like to fade the boxes from the outside in. For example:

_ _ _ _ _ _ _ _ _
+_ _ _ _ _ _ _ _
+_ _ _ _ _ _ _ +
+ + _ _ _ _ _ _ +
+ + _ _ _ _ _ + +
+ + + _ _ _ _ + +

and so forth. What is the best way to figure this out using jQuery?

Here's what I have now (roughly) - give each box div an auto-incrementing metadata id boxid and preform the following:

max = $(".fadeable:last").attr('boxid');
for(i=0;i<max;i++)
{ 
    $("[boxid=" + i + "]").fadeIn('fast');
    $("[boxid=" + (max-i) + "]").fadeIn('fast');
}

is there a better/smoother way to do this? (with animate, or by queuing?) Addtionally, what is the best way to go about arranging the elements in CSS?

Thanks!

A: 
$(".fadeable").each(function() {
    $(this).fadeIn('fast');
});
Josh Pearce
yes, but will this fade them in the order i wanted?
rashcroft22
No, it will fade them all in at the same time, you have to add a delay.
Ambrosia
+2  A: 

Have a play around with this:

<html>
    <head>
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"&gt;&lt;/script&gt;
        <script type="text/javascript">

            function createThem()
            {
                for(var id = 0; id < 15; id++)
                {
                    var el = document.createElement('div');
                    $(el).attr('rel', id);
                    $(el).attr('class', 'fadeable');
                    $(el).css('opacity', '0.0');
                    $(el).css('display', 'inline');
                    $(el).css('background', 'green');
                    $(el).css('float', 'left');
                    $(el).css('margin-right', '5px');
                    $(el).text(id);
                    document.getElementById('container').appendChild(el);
                }
            }

            function fadeThem()
            {
                var max = $(".fadeable:last").attr('rel');
                var timer = 0;
                var command = "";
                for(i=0;i<max;i++)
                {
                    command = "$('.fadeable[rel=" + i + "]').fadeTo('slow', 1.0);";
                    command += "$('.fadeable[rel=" + (max-i) + "]').fadeTo('slow', 1.0);";
                    window.setTimeout(command, timer);
                    timer += 1000;
                }
            }
        </script>
    </head>
    <body>                        
        <button onclick="createThem()" value="Create Them">Create Them</button>
        <button onclick="fadeThem()" value="Fade Them">Fade Them</button>
        <div id="container" style="background:blue;height:200px;width:300px">
            <!--div rel="1" class="fadeable" style="opacity:0.0;display:inline;background:green;float:left;margin-right:5px;">1</div>
            <div rel="2" class="fadeable" style="opacity:0.0;display:inline;background:green;float:left;margin-right:5px;">2</div>
            <div rel="3" class="fadeable" style="opacity:0.0;display:inline;background:green;float:left;margin-right:5px;">3</div>
            <div rel="4" class="fadeable" style="opacity:0.0;display:inline;background:green;float:left;margin-right:5px;">4</div>
            <div rel="5" class="fadeable" style="opacity:0.0;display:inline;background:green;float:left;margin-right:5px;">5</div>
            <div rel="6" class="fadeable" style="opacity:0.0;display:inline;background:green;float:left;margin-right:5px;">6</div>
            <div rel="7" class="fadeable" style="opacity:0.0;display:inline;background:green;float:left;margin-right:5px;">7</div>
            <div rel="8" class="fadeable" style="opacity:0.0;display:inline;background:green;float:left;margin-right:5px;">8</div>
            <div rel="9" class="fadeable" style="opacity:0.0;display:inline;background:green;float:left;margin-right:5px;">9</div>
            <div rel="10" class="fadeable" style="opacity:0.0;display:inline;background:green;float:left;margin-right:5px;">10</div-->
        </div>
   </body>
</html>
Ambrosia
You can remove the createThem() method and button and uncomment the divs in the container if you like, makes no difference which way you do it, I just played around with the dynamic creation.
Ambrosia
A: 

great answer!!!

rashcroft22
+1  A: 

Well, it looked like your question sparked a lot of research! Here is what I came up with. I made it more of a jQuery plugin style, so there is some extra code because of it, but it can be easily reused throughout your project. Additionally, you can set fadeIn to false and it will fade out in the same pattern:

<!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"&gt;&lt;/script&gt; 
<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 what the final opacity should be.

      // We are using a private internal function to handle
      // the processing and delayed fadeIn.
      var fade_action = function(one, two, count_left, delay){
     /* If a callback is present, and this is the last iteration 
        then this sets it up to be called */
        var callback = null;
        if( options.complete && count_left == (steps - 1))
          callback = options.complete;

        /* Always animate 'one' */
        $(one).animate({opacity: fade_to}, {duration: time, complete: callback});
        /* Animate two if its not the same as one.
           two will equal one on the last step of odd numbered sets */
        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);
        }
      }

      // Start the fade
      fade_action(items.get(0), items.get(size - 1), 1, wait);

    }
    return this; // Don't break the chain
  }

  $.fn.fadeFromOutside.defaults = {
    fadeIn: true,
    length: 1000
  }

  /* DOM Ready */
  $(function(){
    $("#items > div").fadeFromOutside({
      fadeIn: true, // Set to false to fade out
      length: 2000, // Take two seconds
      complete: function(){ 
        alert('done!'); // Alert when finished
      }
    });
  });
</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 start as display:none or they need to fadeOut and end as display:none then use the following command instead to initiate the plugin:

// fadeIn: Assumes the div's start as display:none
$("#items > div")
  .css({display: block, opacity: 0.0})
  .fadeFromOutside();

// fadeOut: Will hide all divs at the end
$("#items > div")
  .fadeFromOutside({
    complete: function(){ $("#items > div").hide() }
  });
});
Doug Neiner
A: 

Based on your original code, just make a small adjustment:

    max = $(".fadeable:last").attr('boxid');
    for(i=0;i<max;i++)
    { 
        $("[boxid=" + i + "]").fadeIn('fast', function(){
            $("[boxid=" + (max-i) + "]").fadeIn('fast');
        });

    }

This may not be the exact behaviour you need, but the idea is to chain the fading so that the next element doesnt start animating till the last element has finished.

This is achieved via the callback parameter in the fadeIn function

boz
There still is no delay. Also, the loop does not take into account he wants it to fade from both ends. Your code would fade all the elements in almost simultaneously, and run an extra set of fadeIn's at the end with no effect. You are right that he will want to use some form of nesting.
Doug Neiner