Reputation: 5198
I'm trying to be able to "drag" SVG elements (using Raphael) loaded from a database around a canvas using AJAX. I can load them and display them from the DB fine, but when I want to add event handlers to each individual one, I can't seem to get it right.
I tried using .on() after loading all elements from the DB, when the DOM is ready:
$('circle').on("mousedown", function(event) {
ox = event.screenX;
oy = event.screenY;
event.target.attr({opacity: .5});
dragging = true;
});
But this never seems to get called.
I can add events during the creation of the circles, but then only the last element added actually moves--but only if the mouse is within the X,Y of the other loaded circles:
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")
{
}
}
}
}
});
What am I doing wrong, or better yet, what is the best way to approach this problem?
Upvotes: 0
Views: 821
Reputation: 72445
Depending on the amount of circles it might be a bad idea adding an event listener to each of them. A more robust solution would be adding the event to the svg element
$("#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;
});
Another benefit is that you don't require to load this as callback on ajax success, so you can discard sync problems.
Upvotes: 2
Reputation: 60034
I think the error could be that you refer to c
from inside the mouse event handlers you are attaching to circles.
Then each event handler refers to the object that c
refers to, i.e. the last object. event
carries a target member, and you should use that instead.
I'm using jQuerySVG, and the event' member I'm using is currentTarget, see if is available for you (I think so)
Upvotes: 1