1

Rephrasing this, I asked it poorly before. Hopefully this explains my goal a bit better and if anyone can help I'll be so grateful:

I have two divs set up such that when you click one, the other expands to a height appropriate for its content. The expanding div loads at height:0;overflow:hidden but since the animation requires an actual value instead of height:auto, the height is temporarily switched to 'auto', measured, stored in a variable for use in the animation, and then switched back to zero.

The problem is that the expanding div contains content that the user can choose to view or not view, and if the user views longer content, it gets cut off because the parent div has been set at that pixel value height.

So I would like the expanding div's height to be set back to 'auto' after it expands. Then if the user clicks the button again to close the div, the script will re-measure the height and change it to whatever the current pixel value is so that it can be animated back to zero.

Basically this would be the sequence of events:

  1. Div #2 loads at height:0 and this height is stored in a variable.
  2. Div's height is set to auto.
  3. The auto height is stored as a pixel value.
  4. The height is set back to zero.
  5. User clicks div #1 to open div #2.
  6. Div #2's height animates from zero to the pixel height value.
  7. Its height is set to 'auto' again once the animation is complete.
  8. User views or hides content, which changes the height of the div.
  9. User clicks div #1 to close div #2.
  10. Div #2's current height is measured and stored as another pixel value.
  11. Div #2's height is set to the new pixel value.
  12. Div #2's height is animated back to zero.

Using Box9's brilliant post, I've set up the following code, which successfully accomplishes steps 1 through 6. Step 7 is the important one that I can't figure out, but I'm looking for help with steps 7 through 11.

$(function(){
    var el = $('#ev-donate-form'),
        curHeight = el.height(),
        autoHeight = el.css('height', 'auto').height();
        el.height(curHeight);
    $( "#ev-sponsors" ).click(function() {
        if(el.height() == 0)
            el.height(curHeight).animate({height: autoHeight}, 600);
        else
          el.height(autoHeight).animate({height: curHeight}, 600);
    });
});

I haven't gotten anything to work. I'm thinking maybe to use some kind of setTimeout() attached to the click function that would set the height to auto after the duration of the animation? None of my attempts at that have been successful, but I'm not very experienced with jQuery and it seems like that would work...

Here's a fiddle for experimentation: https://jsfiddle.net/q00bdngk/1/

Shoelaced
  • 846
  • 5
  • 27
  • [`.animate()`](http://api.jquery.com/animate/) provides a `complete` callback. You could set the height to `auto` in there. – Mike Cluck Sep 08 '16 at 19:25
  • 1
    How might I do that? Could I append `.css('height','auto')` to it? – Shoelaced Sep 08 '16 at 19:31
  • Pretty much. `el.height(val).animate({ height: val2, complete: function() { el.css('height', 'auto'); } })` – Mike Cluck Sep 08 '16 at 19:32
  • Hmm... didn't work. Here (if you view the source you'll see that the div still has inline css for the pixel height): https://jsfiddle.net/L3y9shf2/1/ – Shoelaced Sep 08 '16 at 19:48
  • Huh. Strange. Either way, you can actually just pass the function as another argument and [it will work.](https://jsfiddle.net/b9xdzysg/) – Mike Cluck Sep 08 '16 at 19:51
  • You're brilliant! Thanks! This will work for now, but if the content in the div changes length (https://jsfiddle.net/b9xdzysg/1/), do you know how I could get it to store the current height when the user clicks to close the div so that the closing animation is still smooth? – Shoelaced Sep 08 '16 at 20:12
  • Sure. Just [save the height of the element before closing it](https://jsfiddle.net/3cuh2vo6/1/) and use that as the height next time you open it. – Mike Cluck Sep 08 '16 at 20:19
  • You're my damn hero. If you want to put it in an answer I'll accept it! – Shoelaced Sep 08 '16 at 20:30
  • Haha glad I could help! – Mike Cluck Sep 08 '16 at 20:41

1 Answers1

1

The .animate function allows you to pass a complete function. This function will run whenever the animation completes. At that time, you can set the height to auto to allow it to resize as needed.

$(function() {
  var el = $('#ev-donate-form'),
    curHeight = el.height(),
    autoHeight = el.css('height', 'auto').height();
  el.height(curHeight);
  $("#ev-sponsors").click(function() {
    if (el.height() == 0) {
      el.animate({
        height: autoHeight
      }, 600, function() {
        el.css('height', 'auto');
      });
    }
    else {
      el.animate({
        height: curHeight
      }, 600);
    }
  });
});
#ev-sponsors {
  border: 1px solid;
  padding: 1em;
  text-align: center;
  cursor: pointer;
}

#ev-donate-form {
  height: 0;
  overflow: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="ev-sponsors">
  CLICK ME
</div>
<div id="ev-donate-form">
  <p><strong>
  Set the height of this div to 'auto' after the animation that opened it.
  </strong></p>
  <textarea rows="4" cols="50">
    Resize this text area to change the height.
  </textarea>
</div>

But now you've got a problem. When you close it and re-open it, you'll see a jerk in the animation. That's because you need to update what the final height is going to be. Do that just before closing the element and you'll be good to go.

$(function() {
  var el = $('#ev-donate-form'),
    curHeight = el.height(),
    autoHeight = el.css('height', 'auto').height();
  el.height(curHeight);
  $("#ev-sponsors").click(function() {
    if (el.height() == 0) {
      el.animate({
        height: autoHeight
      }, 600, function() {
        el.css('height', 'auto');
      });
    }
    else {
      autoHeight = el.height(); // Update the actual height
      el.animate({
        height: curHeight
      }, 600);
    }
  });
});
#ev-sponsors {
  border: 1px solid;
  padding: 1em;
  text-align: center;
  cursor: pointer;
}

#ev-donate-form {
  height: 0;
  overflow: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="ev-sponsors">
  CLICK ME
</div>
<div id="ev-donate-form">
  <p><strong>
  Set the height of this div to 'auto' after the animation that opened it.
  </strong></p>
  <textarea rows="4" cols="50">
    Resize this text area to change the height.
  </textarea>
</div>
Mike Cluck
  • 31,869
  • 13
  • 80
  • 91