我正在尝试在复杂的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
处理程序的顺序大致为:
move
功能)如果这是正确的,我不明白在气泡阶段中body
的鼠标移动处理程序中停止传播事件会如何破坏拖拽,因为它应该在圆形处理事件之后发生。 / p>
如果有人可以解释这个例子中发生了什么,那将是很好的,特别是我是否误解了事件处理的工作原理,或者Raphaël如何实现拖动的特殊情况。
答案 0 :(得分:3)
我试着在Raphaël邮件列表上询问这个问题,那里的回复解释说Raphaëlmousemove处理程序实际上附加到document
,这解释了我所看到的行为。其中一个回复也解释了为什么拖动需要像这样实现: