Skip to main content

Bug Tracker

Side navigation

#11176 closed bug (invalid)

Opened January 15, 2012 09:33AM UTC

Closed February 27, 2012 03:07PM UTC

Last modified March 14, 2012 10:05AM UTC

Custom queue causes loss of event handler?

Reported by: Nicole Chen <nicole@speakrealenglish.com> Owned by: Nicole Chen <nicole@speakrealenglish.com>
Priority: low Milestone: None
Component: event Version: 1.7.1
Keywords: Cc:
Blocked by: Blocking:
Description

HTML file

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<style>
div.numberBox { float: left; margin: 2%; width: 15%; height: 200px; }
div.active0 { background-color: #ff0000; }
div.active1 { background-color: #111111; }
div.active2 { background-color: #222222; }
div.active3 { background-color: #333333; }
div.active4 { background-color: #444444; }
div.active5 { background-color: #555555; }
div.active6 { background-color: #666666; }
div.active7 { background-color: #777777; }
div.active8 { background-color: #888888; }
div.active9 { background-color: #999999; }
div.active10 { background-color: #0000ff; }
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script>
<script>$.noConflict();</script>
<script type="text/javascript" src="customq.js"></script>
<!-- Using the standard fx queue presents no problems at all. -->
<!--<script type="text/javascript" src="standardq.js"></script>-->
</head>

<body>
<div class="anim">
  <div class="numberBox active0"></div>
  <div class="numberBox active0"></div>
  <div class="numberBox active0"></div>
  <div class="numberBox active0"></div>
  <div class="numberBox active0"></div>
</div>

</body>
</html>

Custom Queue JS

jQuery(document).ready(function($) {
  var anim = {
    mouseenterFunc: function(e) {
      var elem = $(this), queueName = 'animq';
      elem.stop(queueName, true, true); // Stop animation first.
      // Check which animation state we're in, then start to fade in from there.
      var start = 1;
      if (elem.hasClass('active10')) { return true; }
      else if (elem.hasClass('active1')) { start = 1; }
      else if (elem.hasClass('active2')) { start = 2; }
      else if (elem.hasClass('active3')) { start = 3; }
      else if (elem.hasClass('active4')) { start = 4; }
      else if (elem.hasClass('active5')) { start = 5; }
      else if (elem.hasClass('active6')) { start = 6; }
      else if (elem.hasClass('active7')) { start = 7; }
      else if (elem.hasClass('active8')) { start = 8; }
      else if (elem.hasClass('active9')) { start = 9;}
      else { start = 0; }

      var remove = ['active0', 'active1', 'active2', 'active3', 'active4', 'active5', 'active6', 'active7', 'active8', 'active9'],
      add = ['active1', 'active2', 'active3', 'active4', 'active5', 'active6', 'active7', 'active8', 'active9', 'active10'],
      i = start,
      funcs = [function() { elem.switchClass(remove[0], add[0], 1); elem.dequeue(queueName); return true; },
               function() { elem.switchClass(remove[1], add[1], 1); elem.dequeue(queueName); return true; },
               function() { elem.switchClass(remove[2], add[2], 1); elem.dequeue(queueName); return true; },
               function() { elem.switchClass(remove[3], add[3], 1); elem.dequeue(queueName); return true; },
               function() { elem.switchClass(remove[4], add[4], 1); elem.dequeue(queueName); return true; },
               function() { elem.switchClass(remove[5], add[5], 1); elem.dequeue(queueName); return true; },
               function() { elem.switchClass(remove[6], add[6], 1); elem.dequeue(queueName); return true; },
               function() { elem.switchClass(remove[7], add[7], 1); elem.dequeue(queueName); return true; },
               function() { elem.switchClass(remove[8], add[8], 1); elem.dequeue(queueName); return true; },
               function() { elem.switchClass(remove[9], add[9], 1); elem.dequeue(queueName); return true; }];
      for (i = start; i < 10; i++) {
        elem.delay(50, queueName); // 20fps
        elem.queue(queueName, funcs[i]);
      }
      elem.dequeue(queueName);

      return true;
    },

    mouseleaveFunc: function(e) {
      var elem = $(this), queueName = 'animq';
      elem.stop(queueName, true, true); // Stop animation first.
      // Check which animation state we're in, then start to fade out from there.
      start = 0;
      if (elem.hasClass('active0')) { return true; }
      else if (elem.hasClass('active1')) { start = 1; }
      else if (elem.hasClass('active2')) { start = 2; }
      else if (elem.hasClass('active3')) { start = 3; }
      else if (elem.hasClass('active4')) { start = 4; }
      else if (elem.hasClass('active5')) { start = 5; }
      else if (elem.hasClass('active6')) { start = 6; }
      else if (elem.hasClass('active7')) { start = 7; }
      else if (elem.hasClass('active8')) { start = 8; }
      else if (elem.hasClass('active9')) { start = 9;} 
      else if (elem.hasClass('active10')) { start = 10; }

      var add = ['active0', 'active1', 'active2', 'active3', 'active4', 'active5', 'active6', 'active7', 'active8', 'active9'],
      remove = ['active1', 'active2', 'active3', 'active4', 'active5', 'active6', 'active7', 'active8', 'active9', 'active10'],
      i = start,
      funcs = [function() { elem.switchClass(remove[0], add[0], 1); elem.dequeue(queueName); return true; },
               function() { elem.switchClass(remove[1], add[1], 1); elem.dequeue(queueName); return true; },
               function() { elem.switchClass(remove[2], add[2], 1); elem.dequeue(queueName); return true; },
               function() { elem.switchClass(remove[3], add[3], 1); elem.dequeue(queueName); return true; },
               function() { elem.switchClass(remove[4], add[4], 1); elem.dequeue(queueName); return true; },
               function() { elem.switchClass(remove[5], add[5], 1); elem.dequeue(queueName); return true; },
               function() { elem.switchClass(remove[6], add[6], 1); elem.dequeue(queueName); return true; },
               function() { elem.switchClass(remove[7], add[7], 1); elem.dequeue(queueName); return true; },
               function() { elem.switchClass(remove[8], add[8], 1); elem.dequeue(queueName); return true; },
               function() { elem.switchClass(remove[9], add[9], 1); elem.dequeue(queueName); return true; }];
      for (i = start; i > 0; i--) {
        elem.delay(50, queueName); // 20fps
        elem.queue(queueName, funcs[i - 1]);
      }
      elem.dequeue(queueName);

      return true;
    }
  };

  $("div.anim div").mouseenter(anim.mouseenterFunc);

  $("div.anim div").mouseleave(anim.mouseleaveFunc);
});

Standard Queue JS

jQuery(document).ready(function($) {
  var anim = {
    mouseenterFunc: function(e) {
      var elem = $(this);
      elem.stop(true, true); // Stop animation first.
      // Check which animation state we're in, then start to fade in from there.
      var start = 1;
      if (elem.hasClass('active10')) { return true; }
      else if (elem.hasClass('active1')) { start = 1; }
      else if (elem.hasClass('active2')) { start = 2; }
      else if (elem.hasClass('active3')) { start = 3; }
      else if (elem.hasClass('active4')) { start = 4; }
      else if (elem.hasClass('active5')) { start = 5; }
      else if (elem.hasClass('active6')) { start = 6; }
      else if (elem.hasClass('active7')) { start = 7; }
      else if (elem.hasClass('active8')) { start = 8; }
      else if (elem.hasClass('active9')) { start = 9;}
      else { start = 0; }

      var remove = ['active0', 'active1', 'active2', 'active3', 'active4', 'active5', 'active6', 'active7', 'active8', 'active9'],
      add = ['active1', 'active2', 'active3', 'active4', 'active5', 'active6', 'active7', 'active8', 'active9', 'active10'],
      i = start,
      funcs = [function() { elem.switchClass(remove[0], add[0], 1); return true; },
               function() { elem.switchClass(remove[1], add[1], 1); return true; },
               function() { elem.switchClass(remove[2], add[2], 1); return true; },
               function() { elem.switchClass(remove[3], add[3], 1); return true; },
               function() { elem.switchClass(remove[4], add[4], 1); return true; },
               function() { elem.switchClass(remove[5], add[5], 1); return true; },
               function() { elem.switchClass(remove[6], add[6], 1); return true; },
               function() { elem.switchClass(remove[7], add[7], 1); return true; },
               function() { elem.switchClass(remove[8], add[8], 1); return true; },
               function() { elem.switchClass(remove[9], add[9], 1); return true; }];
      for (i = start; i < 10; i++) {
        elem.delay(50); // 20fps
        funcs[i]();
      }

      return true;
    },

    mouseleaveFunc: function(e) {
      var elem = $(this);
      elem.stop(true, true); // Stop animation first.
      // Check which animation state we're in, then start to fade out from there.
      start = 0;
      if (elem.hasClass('active0')) { return true; }
      else if (elem.hasClass('active1')) { start = 1; }
      else if (elem.hasClass('active2')) { start = 2; }
      else if (elem.hasClass('active3')) { start = 3; }
      else if (elem.hasClass('active4')) { start = 4; }
      else if (elem.hasClass('active5')) { start = 5; }
      else if (elem.hasClass('active6')) { start = 6; }
      else if (elem.hasClass('active7')) { start = 7; }
      else if (elem.hasClass('active8')) { start = 8; }
      else if (elem.hasClass('active9')) { start = 9;} 
      else if (elem.hasClass('active10')) { start = 10; }

      var add = ['active0', 'active1', 'active2', 'active3', 'active4', 'active5', 'active6', 'active7', 'active8', 'active9'],
      remove = ['active1', 'active2', 'active3', 'active4', 'active5', 'active6', 'active7', 'active8', 'active9', 'active10'],
      i = start,
      funcs = [function() { elem.switchClass(remove[0], add[0], 1); return true; },
               function() { elem.switchClass(remove[1], add[1], 1); return true; },
               function() { elem.switchClass(remove[2], add[2], 1); return true; },
               function() { elem.switchClass(remove[3], add[3], 1); return true; },
               function() { elem.switchClass(remove[4], add[4], 1); return true; },
               function() { elem.switchClass(remove[5], add[5], 1); return true; },
               function() { elem.switchClass(remove[6], add[6], 1); return true; },
               function() { elem.switchClass(remove[7], add[7], 1); return true; },
               function() { elem.switchClass(remove[8], add[8], 1); return true; },
               function() { elem.switchClass(remove[9], add[9], 1); return true; }];
      for (i = start; i > 0; i--) {
        elem.delay(50); // 20fps
        funcs[i - 1]();
      }

      return true;
    }
  };

  $("div.anim div").mouseenter(anim.mouseenterFunc);

  $("div.anim div").mouseleave(anim.mouseleaveFunc);
});

According to jQuery UI Bug Tracker, this seems like a core bug, not a UI bug.

Attachments (0)
Change History (4)

Changed January 15, 2012 09:56AM UTC by Nicole Chen <nicole@speakrealenglish.com> comment:1

So very very sorry for not reading instructions!!

Custom Queue: http://jsfiddle.net/q9fyx/1/

Standard Queue: http://jsfiddle.net/DCDrv/

Note how the custom queue loses the event handler after flicking the mouse wildly between the div's.

Changed February 08, 2012 01:05PM UTC by sindresorhus comment:2

owner: → Nicole Chen <nicole@speakrealenglish.com>
status: newpending

Thanks for taking the time to contribute to the jQuery project!

However, we do not have the resources to debug big copy/pasted testcases. Can you please resubmit a minimal testcase, reduced to as few lines as possible, showing the issue. We would also be grateful if you could describe the problem in more than one sentence. In addition, when hovering over one of the boxes, it behaves differently in both testcases.

Changed February 11, 2012 10:33AM UTC by Nicole Chen <nicole@speakrealenglish.com> comment:3

status: pendingnew

Hi sindresorhus,

Sorry about that. I did post a jsfiddle testcase. Is that alright? It's as simplified as I can manage already. In brief, it's about starting and stopping and clearing event queues. Note the different behavior between custom queue and fx queue.

Changed February 27, 2012 03:07PM UTC by sindresorhus comment:4

component: unfiledevent
priority: undecidedlow
resolution: → invalid
status: newclosed

I suggest you try asking in the forums, #jquery on Freenode, or on StackOverflow, to determine that it's actually a jQuery bug. If it's determined that it is a jQuery bug, feel free to resubmit a simplified testcase with and a more detailed explanation of the issue.