title: Why is dragging in Raphaël broken by stopping propagation of mousemove in an enclosing element in the bubble phase?
body: <p>I am trying to debug an event handling bug in a complicated web application, but I've reduced the problem to a simple example that demonstrates the behaviour that I'm confused by.</p>
  
  <p>My example page, based one of the Raphaël examples, is as follows:</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  &lt;html lang="en"&gt;
     &lt;head&gt;
        &lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt;
          &lt;title&gt;Raphaël · Drag-n-drop Example&lt;/title&gt;
          &lt;script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"&gt;&lt;/script&gt;
          &lt;script src="http://github.com/DmitryBaranovskiy/raphael/raw/master/raphael-min.js"&gt;&lt;/script&gt;
          &lt;script&gt;
              window.onload = function () {
                  $('body').mousemove(function(e) {
                      // console.log("in body's mousemove");
                      // Uncommenting the next line stops the move
                      // function below from being called:
                      // e.stopPropagation();
                  });
                  var R = Raphael(0, 0, "100%", "100%");
                  var r = R.circle(100, 100, 50).attr({fill: "hsb(0, 1, 1)", stroke: "none", opacity: .5});
                  var start = function () {
                      this.ox = this.attr("cx");
                      this.oy = this.attr("cy");
                      this.animate({r: 70, opacity: .25}, 500, "&gt;");
                  },
                  move = function (dx, dy) {
                      // console.log("in move function for the circle", this);
                      this.attr({cx: this.ox + dx, cy: this.oy + dy});
                  },
                  up = function () {
                      this.animate({r: 50, opacity: .5}, 500, "&gt;");
                  };
                  r.drag(move, start, up);
              };
          &lt;/script&gt;
      &lt;/head&gt;
      &lt;body&gt;
          &lt;div id="holder"&gt;&lt;/div&gt;
      &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>That version works as expected — you can drag the red circle around — but uncommenting the <code>e.stopPropagation()</code> line breaks dragging.  If you have Firebug or Chrome and uncomment the <code>console.log</code> lines, you can see that the <code>move</code> function is never called - somehow the <code>mousemove</code> handler for the <code>body</code> element is being called before the event gets to the circle's handler.</p>
  
  <p>I don't understand how this can be, since the <code>mousemove</code> hander on the <code>body</code> element is set in the bubble phase of event handling.  If I understand <a href="http://www.quirksmode.org/js/events_order.html" rel="nofollow">the order in which events are processed</a> correctly, the order in which <code>mousemove</code> handlers would be called here is approximately:</p>
  
  <ol>
  <li>capture phase: the body element's mousemove (null)</li>
  <li>capture phase: the svg element's mousemove (null)</li>
  <li>capture phase: the circle's mousemove (null)</li>
  <li>bubble phase: the circle's mousemove (set by Raphaël when dragging starts, and which calls the <code>move</code> function)</li>
  <li>bubble phase: the svg element's mousemove (null)</li>
  <li>bubble phase: the body element's mousemove (set as above, and which stops propagation)</li>
  </ol>
  
  <p>If that's right, I don't understand how stopping propagation of the event in the mousemove handler of <code>body</code> in the bubble phase could break dragging, since it should happen after the circle has dealt with the event.</p>
  
  <p>It would be great if someone could explain what's going on in this example, and in particular whether I've misunderstood how the event handling works, or there's something peculiar about how Raphaël implements dragging.</p>