3
\$\begingroup\$

I'm trying to essentially replace an element and make it transition smoothly to the new size... I started off trying to work with the appended element itself, but the padding and margins made that difficult, so I switched to using a container.

var template = "<p>I've replaced the button<br>and in a very smooth<br>fashion!</p>";

var doAnimation = function(e) {
    var parent = $(this).parent();
    var oldHeight = parent.height();

    $(this).fadeOut(400, function() {
        this.remove();

        var paragraph = $(template).appendTo(parent);
        var newHeight = parent.height();

        paragraph.hide().fadeIn();
        parent.height(oldHeight).animate({height: newHeight});
    });
}

$(document).on('click', 'button', doAnimation);

Here is the demo on jsFiddle: first attempt, second attempt

Is there a better way to go about doing this and how would I extract it to something that's reusable?

Edits:

3rd attempt - simply extracted the template to the HTML...

4th attempt - added some data attributes and string replacements.

\$\endgroup\$
2
\$\begingroup\$

If i'm understanding your question correctly what you have is pretty much there already. The only change I can suggest is to let your HTML establish the relationship between your trigger button and the template containing your new HTML like so:

http://jsfiddle.net/vax6hp28/5/

HTML

<div class="container">
    <button data-target="#template-addText">Click Me</button>
</div>

<script id="template-addText" type="text/template">
    <p>I've replaced the button and in a very smooth fashion!</p>
    <p>Holla!</p>
</script>

Javascript

var appendResize = function(e) {
    var parent = $(this).parent();
    var oldHeight = parent.height();
    var templateRef = $($(this).data('target'));

    $(this).fadeOut(400, function() {
        this.remove();

        var template = templateRef.html();
        var paragraph = $(template).appendTo(parent);
        var newHeight = parent.height();

        paragraph.fadeIn(2000);
        parent.height(oldHeight).animate({height: newHeight});
    });
}

$(document).on('click', 'button', appendResize);

This allows you to create as many buttons/template combinations as you like without having to change the javascript.

\$\endgroup\$
  • \$\begingroup\$ Nice. I was actually calling it as an ajax success callback and had a some replacements too. This gave me some ideas... Here (jsfiddle.net/vax6hp28/8) is my updated fiddle with changes I've made. \$\endgroup\$ – user1960364 Nov 21 '14 at 21:05
  • \$\begingroup\$ Looks good! I created a new fiddle based on yours that cleans up the pollution of the global namespace a bit. Probably over-engineered for your needs but here you go: jsfiddle.net/vax6hp28/9 \$\endgroup\$ – Jonathan Crowe Nov 21 '14 at 21:43
  • \$\begingroup\$ Nice. Any reason you didn't place the datasets in the App namespace? \$\endgroup\$ – user1960364 Nov 21 '14 at 23:00
  • \$\begingroup\$ Only because I figured if you are pulling them from AJAX they wouldn't really exist in your application. \$\endgroup\$ – Jonathan Crowe Nov 21 '14 at 23:08
  • \$\begingroup\$ Ahh, well I'm actually not sure how I should handle the data. To explain the use-case, it's a lot like the comments on StackOverflow. A comment button is clicked, it animates a form in to position. The form is is pulled from a template that inserts the proper id. Then, on submit, it uses ajax and on success renders the comment using another template and animates it into position. I'm struggling to figure out how to best handle the data (id before submit and response), any suggestions? \$\endgroup\$ – user1960364 Nov 21 '14 at 23:21
0
\$\begingroup\$

You can use the suggestion of Jonathan Crowe to make it more reusable.

One suggestion I have is that you can tie the resizing animation with the fading in animation this way:

parent.css('opacity',0);
parent.height(oldHeight).animate({height: newHeight, opacity: 1.0},1000);

To make it a little more obvious I set the animation time to 1 full second here.

\$\endgroup\$
  • \$\begingroup\$ Nice! However not an option for how I'm intending wanting it to work. There will be other contents in the parent, so the parent container cannot have it's opacity changed. \$\endgroup\$ – user1960364 Nov 21 '14 at 21:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.