Bug Tracker

Opened 12 years ago

Closed 11 years ago

Last modified 11 years ago

#8892 closed bug (fixed)

Callback is raised before objects are shown with fadeIn() and jQuery.fx.off = true

Reported by: dan@… Owned by: Timmy Willison
Priority: high Milestone: 1.8
Component: effects Version: 1.5.2
Keywords: Cc:
Blocked by: Blocking:

Description

With animations disabled, $('#object').fadeIn(500, callback) calls the user sent callback function before actually showing the object in the DOM.

Example: See jsFiddle at http://jsfiddle.net/kf4vu/22/

With animations enabled, the callback is raised correctly (ex: same code but with animations on , http://jsfiddle.net/yhECL/).

Furthermore, the callback works as expected using .show, ( $('#obj').show(callback) ) with animations either on or off, so this seems to be strictly a fadeIn/fadeOut/similar animations issue.

This causes many issues, especially when trying to .focus() an input field; if the callback is called before the parent element is shown, it doesn't focus (ex: http://jsfiddle.net/bDgav/1/), and jQuery docs even say that IE will throw an error (calling .focus() on hidden element).

This is only an issue with animations off ( jQuery.fx.off = false ), and works as expected with animations on.

Change History (12)

comment:1 Changed 12 years ago by dan@…

A simple workaround for those with this issue (until it's fixed) is to simply first call $(this).show(); in the callback before running any code. For example, see: http://jsfiddle.net/VnS4v/

comment:2 Changed 12 years ago by Timmy Willison

Component: unfiledeffects
Priority: undecidedhigh
Status: newopen

comment:3 Changed 12 years ago by Timmy Willison

http://jsfiddle.net/kf4vu/25/

Computed style is none even though the style has been set to block by jQuery. It has not been repainted when the callback is run. This has to do with setting time to 0, which can manipulate the stack and cause things that should be syncronous to be asyncronous. I'm not sure how to fix this one.

comment:4 Changed 12 years ago by Timmy Willison

Owner: set to Timmy Willison
Status: openassigned

Nevermind, I was mistaken. We'll move the show in the fx prototype show function to before the custom call.

comment:5 Changed 12 years ago by Timmy Willison

Milestone: 1.next1.7

comment:6 Changed 12 years ago by Timmy Willison

We can't do that actually. Having though about it more, the show was put after the custom so that at least one tick could be run to avoid a flash. For instance, consider .fadeIn(). If you have an element that started out as display: none with no opacity set, the element needs to have opacity set to 0 before display can be set to block (or whatever defaultDisplay). However, this is essentially a callback order issue so passing the user callback to the end of stack would fix this issue, but I need to do more research into what problems making the user callback essentially async would cause.

comment:7 Changed 12 years ago by Timmy Willison

Milestone: 1.71.8

We're going to defer this until the effects 1.8 rewrite. I think we can take care of this and #7157 then, without the use of setTimeout.

comment:8 Changed 11 years ago by Youri

If you allow at least one tick to be run to avoid possible flashes, won't you also be able to allow one tick to run when animations are turned off.

Still tho, allowing a single tick is not clean and should be changed. A simpler solution to avoid .fadeIn() flashes would be to simply put the opacity to 0 BEFORE the first tick is called. Thats just a simple check for a special case scenario. When doing this you also remove the one reason why 'the show was put after the custom', meaning u can now put the show before the custom.

comment:9 in reply to:  1 ; Changed 11 years ago by digant@…

Replying to dan@…:

A simple workaround for those with this issue (until it's fixed) is to simply first call $(this).show(); in the callback before running any code. For example, see: http://jsfiddle.net/VnS4v/

Doesn't that just make the thing pop into existence without a fade?

comment:10 in reply to:  9 Changed 11 years ago by elearnapp

Replying to digant@…:

Replying to dan@…:

A simple workaround for those with this issue (until it's fixed) is to simply first call $(this).show(); in the callback before running any code. For example, see: http://jsfiddle.net/VnS4v/

Doesn't that just make the thing pop into existence without a fade?

Yes, but since JQUERY.FX.OFF = TRUE, there is no animation anyhow. And for when animations are enabled (JQUERY.FX.OFF = FALSE), the workaround is still valid, as the animation callback isn't called until after the object is fully visible.

comment:11 Changed 11 years ago by gnarf

Resolution: fixed
Status: assignedclosed

comment:12 Changed 11 years ago by Corey Frang

Fixes #8892: Adding unit test for #8892 - Actually fixed in 58ed62e

Changeset: 7799f21307c3e7c16c1b99b79b8f9f93f969b440

Note: See TracTickets for help on using tickets.