Skip to main content

Bug Tracker

Side navigation

#12837 closed bug (fixed)

Opened November 02, 2012 05:03PM UTC

Closed November 08, 2012 01:25AM UTC

Last modified February 25, 2013 11:05PM UTC

All animations break after zooming a lightbox on the iPad

Reported by: chad.parry@overstock.com Owned by: gnarf
Priority: undecided Milestone: 1.8.3
Component: effects Version: 1.8.2
Keywords: Cc:
Blocked by: Blocking:
Description

Repro steps

1. Lauch Safari on the iPad. I am using Safari version 6.0 with WebKit version 536.26 on iOS version 6.0.

1. Visit the ColorBox examples: http://www.jacklmoore.com/colorbox/example1/. This page currently uses jQuery version 1.8.2, and the bug is also reproducible in version 1.7.1.

1. Open a lightbox by clicking on an example link, such as "Grouped Photo 1."

1. Pinch to zoom in on the image.

1. Tap the "X" button in the corner to close the lightbox.

Expected behavior

The lightbox should close.

Observed behavior

The lightbox does not close. All subsequent jQuery events fail.

Technical information

When the lightbox is zoomed on the iPad, it seems that WebKit is allowing JavaScript events to drop. In particular, there is an event that clears the fxNow variable that gets lost. Since the event handler never runs, then the fxNow variable never gets cleared, so it stays at the same value forever, so the jQuery animation thinks that time has stopped. The result is that jQuery spins in a busy loop, and every time it checks the clock it calculates that the time has not changed, so the animation should not advance.

This bug seems to be triggered only when a user pinches to zoom in on a lightbox. The lightbox has to have the CSS style position:fixed to reproduce the bug.

ColorBox workaround

Since this problem has only been observed when using ColorBox, there is also a ColorBox-specific work-around. The work-around is to disable all animations in ColorBox. The easiest way to do that is to find all invocations of fadeTo in jquery.colorbox.js, and change the first argument to 0. However, the real bug is in jQuery, and this ColorBox modification does not address the root cause.

Patch

The fix is to fire another event to clear the fxNow variable. This will allow the animation to always make forward progress, even if WebKit drops events. Other browsers will still work with this fix in place, because clearing fxNow more than once is both safe and cheap.

--- jquery-1.8.2.js	(original)
+++ jquery-1.8.2.js	(fixed)
@@ -8615,6 +8615,9 @@
 			delete tick.elem;
 		}),
 		tick = function() {
+			setTimeout(function() {
+				fxNow = undefined;
+			}, 0 );
 			var currentTime = fxNow || createFxNow(),
 				remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),
 				percent = 1 - ( remaining / animation.duration || 0 ),

It would be even better to understand exactly what causes the events to be dropped in the first place. That investigation would require more patience and knowledge of WebKit internals than I can muster.

Attachments (0)
Change History (19)

Changed November 02, 2012 05:58PM UTC by chad.parry@overstock.com comment:1

I've created a pull request from my suggested patch: https://github.com/jquery/jquery/pull/1015.

Changed November 02, 2012 06:11PM UTC by rwaldron comment:2

owner: → chad.parry@overstock.com
status: newpending

This is a lot of explanation, but I'd like to see a test case... Historically, jQuery hasn't supported "zoom" related issues because it's been mostly out of scope.

Is this reproducible without human interaction?

Changed November 02, 2012 06:50PM UTC by dmethvin comment:3

there is an event that clears the fxNow variable that gets lost

Do you mean the timer? I think we need to get closer to a root cause before trying to land some sort of fix. This sounds like a Webkit bug that should be reported to them, but a better repro for the specific issue would be helpful.

Perhaps the semantics of setTimeout(fn, 0) has changed? What if you change it to setTimeout(fn, 1) does the problem still happen?

Changed November 05, 2012 04:45PM UTC by anonymous comment:4

@rwaldron: This is not reproducible without human interaction. It only occurs on Safari on the iPad after zooming on a fixed-position lightbox. I don't have any good ideas on how to write a valid unit test.

Changed November 05, 2012 04:47PM UTC by chad.parry@overstock.com comment:5

status: pendingnew

@dmethvin: Sure, I agree that the WebKit behavior is suspect. I'm not a WebKit expert, but I was hoping some other jQuery contributor would know how to resolve a WebKit bug better than I. I don't consider my patch to be a fix as much as a workaround.

I also checked the behavior of setTimeout(fn, 1). The bug still reproduces just like before.

Changed November 07, 2012 11:17PM UTC by Chad Parry <chad.parry@overstock.com> comment:6

After a discussion with some other developers, I've created a new pull request: https://github.com/jquery/jquery/pull/1021. The new version does not fire any spurious clearFxNow events.

Changed November 08, 2012 12:07AM UTC by gnarf comment:7

owner: chad.parry@overstock.comgnarf
status: newassigned

Seems like a somewhat "sane" case to make sure each call to

jQuery.fx.tick()
actually creates a new
fxNow
.

Chad got us more than halfway there, but I reduced the test case down to something more sane, and the patch to something really simple, only adds a few bytes... See https://github.com/jquery/jquery/pull/1022

I could see this in general "covering" our ass in case that

setTimeout( function() { fxNow = undefined; }, 0 );
gets lost for any reason. Exactly WHY it's getting lost on the iPad after zooming still has me lost however.

Changed November 08, 2012 01:25AM UTC by Corey Frang comment:8

resolution: → fixed
status: assignedclosed

Ensure each tick gets it's own fxNow - Fixes #12837 - Thanks @chadparry

Closes gh-1022

Closes gh-1021

Changeset: 781a5c0b78a029b079aae970200d3e4edf543349

Changed November 08, 2012 01:25AM UTC by Corey Frang comment:9

Ensure each tick gets it's own fxNow - Fixes #12837 - Thanks @chadparry

Closes gh-1022

Closes gh-1021

(cherry picked from commit 781a5c0b78a029b079aae970200d3e4edf543349)

Changeset: c56732fd36d45c7c7a95c5f893597c2b755323ad

Changed November 08, 2012 01:30AM UTC by gnarf comment:10

milestone: None1.8.3

Changed November 08, 2012 04:53PM UTC by Chad Parry <chad.parry@overstock.com> comment:11

I confirmed that the fix is working on the iPad. Thanks!

Changed November 11, 2012 08:23PM UTC by dmethvin comment:12

component: unfiledeffects

Changed November 16, 2012 10:56PM UTC by anonymous comment:13

How can I download this updated code?

Changed November 20, 2012 01:29AM UTC by anonymous comment:14

This fix made it into the recently-released jQuery 1.8.3. Download it from http://jquery.com/download/.

Changed January 05, 2013 12:48PM UTC by dinbror comment:15

I'm seeing the same issue with fadeIn/fadeOut in jQuery 1.8.3 but when I use fadeTo instead it works.

I expected this issue would solve it for all effects? Am I wrong?

/dinbror

Changed January 07, 2013 04:15PM UTC by chad.parry@overstock.com comment:16

@dinbror,

I wouldn't expect that you are seeing the same issue, since the code that caused this issue was removed. You have probably hit similar symptoms from a different issue.

I recommend you file a separate bug. Include a description of what you were doing, your browser version, and a minimal JS example if you can.

Changed February 22, 2013 12:59AM UTC by shay.grantham@ngv.vic.gov.au comment:17

Hi All,

I've been having the same problem with colorbox and zoom on an ipad. I have tried using jquery 1.8.2 and the latest during testing. My function looks like this:

$('.ajax').colorbox({

onComplete : function() { $(this).colorbox.resize(); },

scrolling: false,

innerWidth: "553",

escKey: true,

transition: "fade",

overlayClose: true

});

Still not working! Any suggestions or ideas?

Changed February 22, 2013 01:03AM UTC by shay.grantham@ngv.vic.gov.au comment:18

Hi All,

I've been having the same problem with colorbox and zoom on an ipad. I have tried using jquery 1.8.2 and the latest during testing. I'm using a fade transition and an onComplete callback to resize the colorbox (due to our image retrieval process not imcluding width and height dimensions).

Still not working! Any suggestions or ideas?

Changed February 25, 2013 11:05PM UTC by anonymous comment:19

@shay.grantham,

You mentioned using jQuery 1.8.2 "and the latest." I just wanted to confirm that you mean you have also tried 1.9.1, which contains the fix for this bug. If you still see a hang with any versions since 1.8.3, then I recommend you file a separate ticket. If you know how to check for JavaScript errors, then attaching those to the ticket would be helpful.