Почему перетаскивание в Raphaël прерывается, останавливая распространение мышиного движения в охватывающем элементе в фазе пузыря? - PullRequest
3 голосов
/ 08 июля 2011

Я пытаюсь отладить ошибку обработки событий в сложном веб-приложении, но я сократил проблему до простого примера, демонстрирующего поведение, которое меня смущает.

Моя страница примера,Основываясь на одном из примеров 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 установлен в пузырьковой фазе обработки событий.Если я понимаю порядок, в котором события обрабатываются правильно, то порядок, в котором здесь будут вызываться обработчики mousemove, примерно такой:

  1. фаза захвата: mousemove элемента тела (null)
  2. фаза захвата: перемещение мыши по элементу svg (ноль)
  3. фаза захвата: движение мыши по кругу (ноль)
  4. фаза пузыря: движение мыши по кругу (устанавливается Рафаэлем, когданачинается перетаскивание, которое вызывает функцию move)
  5. пузырьковая фаза: перемещение мыши по элементу svg (ноль)
  6. пузырьковая фаза: перемещение мыши по элементу тела (устанавливается, как указано выше, и которое останавливает распространение)

Если это правильно, я не понимаю, как остановка распространения события в обработчике мышиного движения body в фазе пузыря может прервать перетаскивание, поскольку это должно произойти после того, как круг прошелс событием.

Было бы здорово, если бы кто-то мог объяснить, что происходит в этом примере, и, в частности, правильно ли я понял, какобработка событий работает, или есть что-то особенное в том, как Raphaël реализует перетаскивание.

1 Ответ

3 голосов
/ 11 июля 2011

Я пытался спросить об этом в списке рассылки Raphaël, и ответы там объясняют, что обработчик Raphaël mousemove фактически привязан к document, что объясняет поведение, которое я видел.В одном из ответов также объясняется, почему перетаскивание должно быть реализовано так:

...