为什么在气泡阶段中通过停止鼠标移动在封闭元素中的传播来破坏拉斐尔的拖动?

问题描述 投票:3回答:1

[我正在尝试调试复杂的Web应用程序中的事件处理错误,但已将问题简化为一个简单的示例,该示例演示了我所困惑的行为。

基于Raphaël的示例之一,我的示例页面如下:

<!DOCTYPE html>
<html lang="en">
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Raphaël · Drag-n-drop Example</title>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
        <script src="http://github.com/DmitryBaranovskiy/raphael/raw/master/raphael-min.js"></script>
        <script>
            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, ">");
                },
                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, ">");
                };
                r.drag(move, start, up);
            };
        </script>
    </head>
    <body>
        <div id="holder"></div>
    </body>
</html>

该版本按预期工作-您可以拖动红色圆圈-但取消注释e.stopPropagation()行会中断拖动。如果您使用Firebug或Chrome浏览器,并且取消了console.log行的注释,则可以看到move函数从不被调用-在事件到达圈子的处理程序之前,将以某种方式调用mousemove元素的body处理程序。

我不知道怎么回事,因为mousemove元素上的body处理程序是在事件处理的起泡阶段设置的。如果我正确理解the order in which events are processed,则在此处调用mousemove处理程序的顺序大致为:

  1. 捕获阶段:主体元素的鼠标移动(空)
  2. 捕获阶段:svg元素的mousemove(空)
  3. 捕获阶段:圆圈的鼠标移动(空)
  4. 气泡阶段:圆圈的鼠标移动(拖动开始时由Raphaël设置,并调用move函数)
  5. 气泡阶段:svg元素的mousemove(空)
  6. 气泡阶段:主体元素的鼠标移动(如上设置,并停止传播)

[如果是正确的话,我不明白在气泡阶段停止事件在body的mousemove处理程序中传播将如何中断拖动,因为它应该在圆处理事件之后发生。

[如果有人能解释此示例中发生的事情,特别是我是否误解了事件处理的工作原理,或者Raphaël如何实施拖动有些特殊之处,那就太好了。

javascript dom-events raphael event-bubbling
1个回答
3
投票

我曾尝试在Raphaël邮件列表中询问此问题,并且那里的答复说明Raphaëlmousemove处理程序实际上附加在document上,这解释了我所看到的行为。答复之一还解释了为什么需要像这样实现拖动:

© www.soinside.com 2019 - 2024. All rights reserved.