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.
2 Answers 2
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.
-
\$\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– user19603642014年11月21日 21:05:17 +00:00Commented Nov 21, 2014 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– Jonathan Crowe2014年11月21日 21:43:43 +00:00Commented Nov 21, 2014 at 21:43
-
\$\begingroup\$ Nice. Any reason you didn't place the datasets in the App namespace? \$\endgroup\$user1960364– user19603642014年11月21日 23:00:31 +00:00Commented Nov 21, 2014 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– Jonathan Crowe2014年11月21日 23:08:01 +00:00Commented Nov 21, 2014 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 properid
. 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– user19603642014年11月21日 23:21:13 +00:00Commented Nov 21, 2014 at 23:21
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.
-
\$\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– user19603642014年11月21日 21:06:57 +00:00Commented Nov 21, 2014 at 21:06