Side navigation
#2503 closed bug (duplicate)
Opened March 13, 2008 06:33PM UTC
Closed February 18, 2009 03:38AM UTC
jQuery.fx.update does not account for inline-block elements.
Reported by: | apramanik | Owned by: | |
---|---|---|---|
Priority: | minor | Milestone: | |
Component: | effects | Version: | 1.2.3 |
Keywords: | Cc: | ||
Blocked by: | Blocking: |
Description
I was getting popping in my animations for inline-block
(or -moz-inline-box) spans due to them being changed to blocks in jQuery.fx.prototype. I fixed it by making the following changes:
jQuery.fx.prototype = { // Simple function for setting a style value update: function(){ if ( this.options.step ) this.options.step.apply( this.elem, [ this.now, this ] ); (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this ); // Set display property to block for height/width animations if ( this.prop == "height" || this.prop == "width" ) this.elem.style.display = "block"; },
to
jQuery.fx.prototype = { // Simple function for setting a style value update: function(){ if ( this.options.step ) this.options.step.apply( this.elem, [ this.now, this ] ); (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this ); var comp_display = jQuery( this.elem ).css( 'display' ); // Set display property to block for height/width animations, if it isn't a // block value already. if ( ( this.prop == "height" || this.prop == "width" ) && comp_display != "inline-block" && comp_display != "-moz-inline-box" && comp_display != "block" ) this.elem.style.display = "block"; },
As mentioned by John Resig, this solution would be slow because it is computing the display property on every frame of animation.
Attachments (0)
Change History (4)
Changed March 13, 2008 11:11PM UTC by comment:1
Changed March 13, 2008 11:56PM UTC by comment:2
You can't specify what display to transition to on a 'show'. So I made the following changes to allow specification of a display attribute ( e.g. $j( 'a' ).animate( { height: 'show', display : 'inline-block' } ) ). If it isn't specified then it defaults to 'block':
// Simple function for setting a style value update: function(){ if ( this.options.step ) this.options.step.apply( this.elem, [ this.now, this ] ); (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this ); // Set display property to block for height/width animations, if it isn't a // block value already. if ( ( this.prop == "height" || this.prop == "width" ) && this.options.display != "inline-block" && this.options.display != "-moz-inline-box" && this.options.display != "block" ) { this.elem.style.display = this.options.to_display ? this.options.to_display : "block"; } },
...
step: function(gotoEnd){ var t = (new Date()).getTime(); if ( gotoEnd || t > this.options.duration + this.startTime ) { this.now = this.end; this.pos = this.state = 1; this.update(); this.options.curAnim[ this.prop ] = true; var done = true; for ( var i in this.options.curAnim ) if ( this.options.curAnim[i] !== true ) done = false; if ( done ) { if ( this.options.display != null ) { // Reset the overflow this.elem.style.overflow = this.options.overflow; // Reset the display this.elem.style.display = this.options.display; if ( jQuery.css(this.elem, "display") == "none" ) this.elem.style.display = this.options.to_display ? this.options.to_display : "block"; }
...
animate: function( prop, speed, easing, callback ) { var optall = jQuery.speed(speed, easing, callback); return this[ optall.queue === false ? "each" : "queue" ](function(){ if ( this.nodeType != 1) return false; var opt = jQuery.extend({}, optall); var hidden = jQuery(this).is(":hidden"), self = this; for ( var p in prop ) { if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden ) return jQuery.isFunction(opt.complete) && opt.complete.apply(this); if ( p == "height" || p == "width" ) { // Store display property opt.display = jQuery.css(this, "display"); opt.to_display = prop['display']; // Make sure that nothing sneaks out opt.overflow = this.style.overflow; } }
That's the best I could think of so far. I'm not fond of the conditionals and would rather just default this.options.to_display to 'block', but I'm not sure where the best place to put that would be.
Changed March 13, 2008 11:56PM UTC by comment:3
The changes are all near the bottom of the code.
Change comp_display to this.options.display. This is computed on effect creation.