我正在尝试使用AJAX“拖动”从画布周围的数据库加载的SVG元素(使用Raphael)。我可以加载它们并从数据库中显示它们,但是当我想为每个人添加事件处理程序时,我似乎无法做到正确。
当DOM准备好后,我尝试在加载DB中的所有元素后使用.on():
$('circle').on("mousedown", function(event) {
ox = event.screenX;
oy = event.screenY;
event.target.attr({opacity: .5});
dragging = true;
});
但这似乎永远不会被召唤。
我可以在创建圆圈期间添加事件,但只有最后添加的元素才会移动 - 但前提是鼠标位于其他加载圆圈的X,Y之内:
var data = $.ajax({
type: "POST",
url: "map.php",
data: "loadMap=1",
success: function(text) {
var item = text.split(";");
for (x in item)
{
if (item[x].length > 0)
{
var str = item[x].split(",");
if (str[0] == "node")
{
var c = svg.circle(str[1], str[2], 10);
c.attr("id", str[3]);
c.attr("fill", "black");
c.attr("stroke", "none");
c.mousedown(function(event) {
ox = event.screenX;
oy = event.screenY;
c.attr({opacity: .5});
dragging = true;
});
c.mousemove(function(event) {
if (dragging) {
c.translate(event.screenX - ox, event.screenY - oy);
ox = event.screenX;
oy = event.screenY;
}
});
c.mouseup(function(Event) {
dragging = false;
c.attr({opacity: 1});
});
}
else if (str[0] == "room")
{
}
}
}
}
});
我做错了什么,或者更好的是,解决这个问题的最佳方法是什么?
答案 0 :(得分:2)
根据圈子的数量,向每个圈子添加一个事件侦听器可能是一个坏主意。更强大的解决方案是将事件添加到svg元素
$("#svgelement").on("mousedown", "circle", function(event){
target = this;
ox = event.screenX;
oy = event.screenY;
target.setAttribute('opacity', 0.5)
dragging = true;
});
$("#svgelement").on("mousemove", function(event){
if (dragging) {
if(target) target.setAttribute('transform', 'translate('+ event.screenX - ox +','+ event.screenY - oy +')');
ox = event.screenX;
oy = event.screenY;
}
});
//attached to the window, otherwise you might drag
//all the way out of the svg and release there.
$(window).on("mouseup", function(Event) {
dragging = false;
target.setAttribute('opacity', 1)
target = false;
});
另一个好处是你不需要加载它作为ajax成功的回调,所以你可以放弃同步问题。
答案 1 :(得分:1)
我认为错误可能是您从附加到圈子的鼠标事件处理程序中引用c
。
然后每个事件处理程序引用c
引用的对象,即最后一个对象。 event
带有目标成员,您应该使用该成员。
我正在使用jQuerySVG,而我正在使用的活动成员是 currentTarget ,看看是否可以使用(我认为是这样)