Bug Tracker

Ticket #8892 (closed bug: fixed)

Opened 4 years ago

Last modified 2 years ago

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

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

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

comment:1 follow-up: ↓ 9 Changed 4 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 4 years ago by timmywil

  • Priority changed from undecided to high
  • Status changed from new to open
  • Component changed from unfiled to effects

comment:3 Changed 3 years ago by timmywil

 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 3 years ago by timmywil

  • Owner set to timmywil
  • Status changed from open to assigned

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

comment:5 Changed 3 years ago by timmywil

  • Milestone changed from 1.next to 1.7

comment:6 Changed 3 years ago by timmywil

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 3 years ago by timmywil

  • Milestone changed from 1.7 to 1.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 3 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 ; follow-up: ↓ 10 Changed 2 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 2 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 2 years ago by gnarf

  • Status changed from assigned to closed
  • Resolution set to fixed

comment:12 Changed 2 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.