Bug Tracker

Opened 7 years ago

Closed 7 years ago

Last modified 7 years ago

#11176 closed bug (invalid)

Custom queue causes loss of event handler?

Reported by: Nicole Chen <nicole@…> Owned by: Nicole Chen <nicole@…>
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.

Change History (4)

comment:1 Changed 7 years ago by Nicole Chen <nicole@…>

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.

comment:2 Changed 7 years ago by sindresorhus

Owner: set to Nicole Chen <nicole@…>
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.

comment:3 Changed 7 years ago by Nicole Chen <nicole@…>

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.

comment:4 Changed 7 years ago by sindresorhus

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.

Note: See TracTickets for help on using tickets.