操纵动态创建的SVG元素

时间:2012-07-31 05:10:51

标签: jquery ajax svg

我正在尝试使用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")
                {
                }
            }
        }
    }
});

我做错了什么,或者更好的是,解决这个问题的最佳方法是什么?

2 个答案:

答案 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 ,看看是否可以使用(我认为是这样)