Bug Tracker

Ticket #9678 (closed bug: fixed)

Opened 3 years ago

Last modified 3 years ago

setInterval cleared by animation

Reported by: kertesz@… Owned by: timmywil
Priority: low Milestone: 1.6.3
Component: effects Version: 1.6.1
Keywords: Cc:
Blocking: Blocked by:

Description

In Google Chrome setInterval callback will not execute when preceded by jQuery animation, see code below.

  • Tested with Chrome 11.0.696.60
  • Only when loaded into new browser tab! Will run as expected after page refresh.
  • No trouble in IE8
  • No trouble with jQuery 1.5.2
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.6.1.min.js"></script>
<script>

$(document).ready( function () {
	$('#box').slideUp();
} );

function tick() {
	$('#ticks').append('+');
}

setInterval(tick, 1000);

</script>
</head>

<body>
   <div id="box">XXX</div>
   <div id="ticks"></div>
</body>
</html>

My guess is that interval timer ID = 1 is affected by the jQuery animation code.

Change History

comment:1 Changed 3 years ago by rwaldron

  • Priority changed from undecided to low
  • Resolution set to worksforme
  • Status changed from new to closed
  • Component changed from unfiled to effects

Works for me in latest Chrome with jQuery Edge:  http://jsfiddle.net/rwaldron/7SwMx/

comment:2 Changed 3 years ago by kertesz@…

Sorry I did not tell that you cannot reproduce this is jsFiddle. Please try code on its own.

comment:3 Changed 3 years ago by kertesz@…

OK, I got it.

Look at the 1.6.1 source, within jQuery.custom() we have

8356 timerId = 1;

Now if we do have requestAnimationFrame, as is the case with Chrome, raf is passed as callback to requestAnimationFrame, so raf will execute jQuery.fx.tick which eventually calls jQuery.fx.stop, which has

8480 clearInterval( timerId );

thus killing my interval timer.

But why do we have timerId = 1 in the first place?

comment:4 Changed 3 years ago by anonymous

Hi there, I just wanted to comment on this to mention that I've just hit this bug myself (Chrome 12.0.742.100, jQuery 1.6.1) and came to the exact same conclusion about the explicit call to set timerId to 1 and then calling clearInterval(timerId) even if the animation wasn't kicked off with setInterval.

I worked around it by creating a dummy setInterval first so that my real update function has an ID that's >= 2.

When reproducing this it's critical to start in a fresh browser tab (as mentioned in the original bug) because after a refresh your first setInterval will have an ID that isn't 1.

comment:5 Changed 3 years ago by timmywil

  • Status changed from closed to reopened
  • Resolution worksforme deleted

timerId was set to 1 because it's a short way to set a truthy value. The number 1 is not significant, so if it is conflicting with a timer id, we can set it to some other truthy value.

Something to watch timer ids:  http://jsfiddle.net/timmywil/Qnbns/1/

comment:6 Changed 3 years ago by timmywil

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

Confirmed

comment:7 Changed 3 years ago by timmywil

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

Set timerId to true instead of a number so that intervals set to 1 are not accidentally cleared when stopped. Fixes #9678.

comment:8 Changed 3 years ago by timmywil

  • Milestone changed from 1.next to 1.6.2

comment:9 Changed 3 years ago by supersi2000

This bug doesn't seem to be fixed in 1.6.2. I just tried the test case in the original report (updating the script tag to pull in 1.6.2) and it still fails.

comment:10 Changed 3 years ago by timmywil

The only way that would be possible would be if clearInterval( true ) cleared the timer id of 1, which I'm surprised to learn that it does.  http://jsfiddle.net/timmywil/ePVAZ/1/show/

However, I am only able to reproduce this when jQuery is not included on the page.

comment:11 Changed 3 years ago by anonymous

I think this ticket needs to be reopened given the previous comment. I'm seeing the same results with the jsfiddle link provided.

It seems dangerous to call clearInterval on a value unless we know it's a valid timerId. What about wrapping the call to clearInterval in an if statement: if (typeof timerId === 'number') {

clearInterval(timerId);

} timerId = null;

comment:12 Changed 3 years ago by timmywil

  • Status changed from closed to reopened
  • Resolution fixed deleted

You're right

comment:13 Changed 3 years ago by timmywil

  • Status changed from reopened to open
  • Milestone changed from 1.6.2 to 1.next

For 1.6.3

comment:14 Changed 3 years ago by timmywil

  • Status changed from open to closed
  • Resolution set to fixed
  • Milestone changed from 1.next to 1.6.3

This is fixed for 1.6.3.

Note: See TracTickets for help on using tickets.