jQuery: The Write Less, Do More JavaScript Library

Ticket #1942 (closed bug: fixed)

Opened 6 months ago

Last modified 6 months ago

animating width/height of bordered objects in Opera

Reported by: wizzud Assigned to: davidserduke
Type: bug Priority: major
Milestone: 1.2.2 Component: fx
Version: 1.2.1 Keywords: opera animate borders
Cc: Needs: Review

Description

Came across this problem whereby width/height animation in Opera, of an object that has a border, causes 'jumps' in the object size before resizing.

Demo and fix : http://www.wizzud.com/tester/operabug.html

This occurs because the borders are being included in the starting width and height when initialising the animation. The problem is located in fx.cur(), when curCSS() is used to get the width/height values.

I can only find this problem in Opera (tried IE6, IE7, FF1.5, FF2, Safari 2, Safari 3beta).

I have a rough patch (see below and demo) that fixes it, based on the theory that if width() and height() are the standard API methods for determining those particular values then why should animate() not use them too.

/* THE FIX : ...*/ jQuery.fx.prototype.cur = function(force){

if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )

return this.elem[ this.prop ];

//wizzud...(opera screws up animation with borders)...inserted

if( this.prop == 'width' this.prop == 'height')

return parseFloat(jQuery.css(this.elem, this.prop));

//wizzud...end of insert

var r = parseFloat(jQuery.curCSS(this.elem, this.prop, force));

return r && r > -10000 ? r : parseFloat(jQuery.css(this.elem, this.prop)) 0;

};

Attachments

1942.diff (1.2 kB) - added by davidserduke 6 months ago.
proposed patch

Change History

Changed 6 months ago by davidserduke

  • status changed from new to assigned
  • owner set to davidserduke

You make a compelling test case. :)

I made a slight modification to your fix. It is essentially the same thing. jQuery.css calls jQuery.curCSS unless it is width/height so it is already doing that check. See if my logic makes sense here.

Current cur function:

cur: function(force){
  if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
    return this.elem[ this.prop ];
  var r = parseFloat(jQuery.curCSS(this.elem, this.prop, force));
  return r && r > -10000 ? r : parseFloat(jQuery.css(this.elem, this.prop)) || 0;
},

New cur function:

cur: function(force){
  if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
    return this.elem[ this.prop ];
  var r = parseFloat(jQuery.css(this.elem, this.prop, force));
  return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
},

jQuery.css calls jQuery.curCSS directly UNLESS it is width and height. So making the change to the 'var r' line to call .css instead of .curCSS (passing through force) is essentially putting in wizzud's fix. At this point I also changed the second function. If r is "false" or bad it tries the jQuery.curCSS call again without force to see if that can get the value and returns 0 if it can't. Since jQuery.css only does something different on width and height it makes sense to bypass .css and move to .curCSS since we already know .css has returned something bad !(r && r > -10000).

Changed 6 months ago by davidserduke

proposed patch

Changed 6 months ago by davidserduke

  • status changed from assigned to closed
  • resolution set to fixed

Fixed in [3958].

Note: See TracTickets for help on using tickets.