Поведение перетаскивания для вложенных элементов g
Этот вопрос тесно связан со следующим вопросом:
В этом вопросе в группе был один элемент g с кучей элементов svg. Решение состояло в том, чтобы использовать d3.event.sourceEvent.stopPropagation на dragstart.
В моем случае у меня есть один элемент g с кучей элементов svg, включая другие элементы g. Вот простой пример, который я создал, который иллюстрирует мою проблему: http://jsfiddle.net/eforgy/x1cwur41/ (код скопирован ниже).
Скрипка создает три вложенных элемента g, и каждый элемент g содержит только один прямоугольник. Если вы откроете консоль и нажмете на самый красный красный прямоугольник, несмотря на наличие stopPropagation на dragstart, вы увидите, что он распространяется от верхнего красного прямоугольника к нижнему синему прямоугольнику, и когда вы начинаете перетаскивать, он использует перетаскивание из синий прямоугольник, т.е. все три прямоугольника движутся. Поведение, которое я пытаюсь воспроизвести, таково:
- Если вы перетаскиваете синий прямоугольник, все три прямоугольника перемещаются вместе.
- Если вы перетащите зеленый прямоугольник, синий прямоугольник не будет двигаться, но зеленый и красный прямоугольники будут двигаться вместе
- Если вы перетаскиваете красный прямоугольник, перемещается только красный прямоугольник.
Любая помощь будет оценена.
PS: вот код:
var child = {index: 0};
var w = 800,
h = 600;
var svg = d3.select("body").append("svg")
.attr("width", w)
.attr("height", h);
var cinit = function() {
return svg;
};
cinit.x = 0;
cinit.y = 0;
cinit.width = w;
cinit.height = h;
var c0 = new Component(cinit); c0.fill = "blue";
var c1 = new Component(c0); c1.fill = "green";
var c2 = new Component(c1); c2.fill = "red";
function Component(parent) {
var id = child.index;
child.index += 1;
console.log("Created component "+id);
var x = 1.1*parent.x;
var y = 1.1*parent.y;
var width = .5*parent.width;
var height = .5*parent.height;
var fill = "blue";
var stroke = "black";
var drag = d3.behavior.drag()
.origin(function() {
var t = d3.transform(group.attr("transform")).translate;
return {
x: t[0],
y: t[1]
};
})
.on("drag", function() {
console.log("drag: "+id);
var p = component.position;
p[0] = d3.event.x;
p[1] = d3.event.y;
component.position = p;
})
.on("dragstart", function() {
console.log("dragstart: "+id);
d3.event.sourceEvent.stopPropagation;
});
var group = parent().append("g")
.attr("transform", "translate("+x+","+y+")")
.call(drag);
var rect = group.append("rect")
.attr("width", width)
.attr("height", height)
.attr("fill", fill)
.attr("stroke", stroke)
.on("click", function() {console.log("Clicked "+id);});
function component() {
return group;
};
Object.defineProperty(component,"position",{
get: function() {return [x, y, width, height];},
set: function(_) {
x = _[0];
y = _[1];
width = _[2];
height = _[3];
rect.attr("width", width).attr("height", height);
group.attr("transform", "translate("+x+","+y+")");
return component;
}
});
Object.defineProperty(component,"x",{
get: function() {return x;},
set: function(_) {
x = _;
group.attr("transform", "translate("+x+","+y+")");
return component;
}
});
Object.defineProperty(component,"y",{
get: function() {return y;},
set: function(_) {
y = _;
group.attr("transform", "translate("+x+","+y+")");
return component;
}
});
Object.defineProperty(component,"width",{
get: function() {return width;},
set: function(_) {
width = _;
rect.attr("width", width).attr("height", height);
return component;
}
});
Object.defineProperty(component,"height",{
get: function() {return height;},
set: function(_) {
height = _;
rect.attr("width", width).attr("height", height);
return component;
}
});
Object.defineProperty(component,"fill",{
get: function() {return fill;},
set: function(_) {
fill = _;
rect.attr("fill", fill);
return component;
}
});
return component;
}
1 ответ
Проблема в том, что вы не вызываете функцию d3.event.sourceEvent.stopPropagation
, Вам не хватает скобок ()
в конце.
В случае сомнений не забудьте проверить документацию D3;)