可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
So this might be really simple, but I haven't been able to find any examples to learn off of yet, so please bear with me. ;)
Here's basically what I want to do:
<div>Lots of content! Lots of content! Lots of content! ...</div>
....
$("div").html("Itsy-bitsy bit of content!");
I want to smoothly animate between the dimensions of the div with lots of content to the dimensions of the div with very little when the new content is injected.
Thoughts?
回答1:
Try this jQuery plugin:
// Animates the dimensional changes resulting from altering element contents
// Usage examples:
// $("#myElement").showHtml("new HTML contents");
// $("div").showHtml("new HTML contents", 400);
// $(".className").showHtml("new HTML contents", 400,
// function() {/* on completion */});
(function($)
{
$.fn.showHtml = function(html, speed, callback)
{
return this.each(function()
{
// The element to be modified
var el = $(this);
// Preserve the original values of width and height - they'll need
// to be modified during the animation, but can be restored once
// the animation has completed.
var finish = {width: this.style.width, height: this.style.height};
// The original width and height represented as pixel values.
// These will only be the same as `finish` if this element had its
// dimensions specified explicitly and in pixels. Of course, if that
// was done then this entire routine is pointless, as the dimensions
// won't change when the content is changed.
var cur = {width: el.width()+'px', height: el.height()+'px'};
// Modify the element's contents. Element will resize.
el.html(html);
// Capture the final dimensions of the element
// (with initial style settings still in effect)
var next = {width: el.width()+'px', height: el.height()+'px'};
el .css(cur) // restore initial dimensions
.animate(next, speed, function() // animate to final dimensions
{
el.css(finish); // restore initial style settings
if ( $.isFunction(callback) ) callback();
});
});
};
})(jQuery);
Commenter RonLugge points out that this can cause problems if you call it twice on the same element(s), where the first animation hasn't finished before the second begins. This is because the second animation will take the current (mid-animation) sizes as the desired "ending" values, and proceed to fix them as the final values (effectively stopping the animation in its tracks rather than animating toward the "natural" size)...
The easiest way to resolve this is to call stop()
before calling showHtml()
, and passing true
for the second (jumpToEnd) parameter:
$(selector).showHtml("new HTML contents")
.stop(true, true)
.showHtml("even newer contents");
This will cause the first animation to complete immediately (if it is still running), before beginning a new one.
回答2:
You can use the animate method.
$("div").animate({width:"200px"},400);
回答3:
maybe something like this?
$(".testLink").click(function(event) {
event.preventDefault();
$(".testDiv").hide(400,function(event) {
$(this).html("Itsy-bitsy bit of content!").show(400);
});
});
Close to what I think you wanted, also try slideIn/slideOut or look at the UI/Effects plugin.
回答4:
Here is how I fixed this, I hope this will be usefull !
The animation is 100% smooth :)
HTML:
<div id="div-1"><div id="div-2">Some content here</div></div>
Javascript:
// cache selectors for better performance
var container = $('#div-1'),
wrapper = $('#div-2');
// temporarily fix the outer div's width
container.css({width: wrapper.width()});
// fade opacity of inner div - use opacity because we cannot get the width or height of an element with display set to none
wrapper.fadeTo('slow', 0, function(){
// change the div content
container.html("<div id=\"2\" style=\"display: none;\">new content (with a new width)</div>");
// give the outer div the same width as the inner div with a smooth animation
container.animate({width: wrapper.width()}, function(){
// show the inner div
wrapper.fadeTo('slow', 1);
});
});
There might be a shorter version of my code, but I just kept it like this.
回答5:
This does the job for me. You can also add a width to the temp div.
$('div#to-transition').wrap( '<div id="tmp"></div>' );
$('div#tmp').css( { height: $('div#to-transition').outerHeight() + 'px' } );
$('div#to-transition').fadeOut('fast', function() {
$(this).html(new_html);
$('div#tmp').animate( { height: $(this).outerHeight() + 'px' }, 'fast' );
$(this).fadeIn('fast', function() {
$(this).unwrap();
});
});
回答6:
Hello meyahoocoma4c5ki0pprxr19sxhajsogo6jgks5dt.
You could wrap the 'content div' with an 'outer div' which is set to an absolute width value. Inject the new content with a "hide()" or "animate({width})" method, shown in the other answers. This way, the page doesn't reflow in between because the wrapper div holds a steady width.
回答7:
You can smooth out the jQuery animation using dequeue
. Test for presence of class (set upon hover and removed on mouseOut animate callback) before staring new animation. When new animation does start, dequeue.
Here's a quick demo.
var space = ($(window).width() - 100);
$('.column').width(space/4);
$(".column").click(function(){
if (!$(this).hasClass('animated')) {
$('.column').not($(this).parent()).dequeue().stop().animate({width: 'toggle', opacity: '0.75'}, 1750,'linear', function () {});
}
$(this).addClass('animated');
$('.column').not($(this).parent()).dequeue().stop().animate({width: 'toggle', opacity: '0.75'}, 1750,'linear', function () {
$(this).removeClass('animated').dequeue();
});
$(this).dequeue().stop().animate({
width:(space/4)
}, 1400,'linear',function(){
$(this).html('AGAIN');
});
});
The demo is setup as 5 full-height columns, clicking any of the columns 2 thru 5 will animate toggle width of the other 3 and move the clicked element to the far left.
回答8:
To piggy-back on the jquery plugin solution (too low of reputation to add this as a comment) jQuery.html() will remove any event handlers on the appended html. Changing:
// Modify the element's contents. Element will resize.
el.html(html);
to
// Modify the element's contents. Element will resize.
el.append(html);
will retain the event handlers of the "html" elements