似乎 D3.drag 支持拖动但不支持“拖放”,即它不支持检测 dragenter、dragleave 和 dragover 事件。我可以让 D3 创建的对象来监听这些事件,但不能使 D3 对象可拖动而不访问拖动事件属性。
这是我的代码。
我创建了一个可拖动的 svg 圆圈、一个可拖动的 D3 圆圈和一个拖动 D3 圆圈。
svg 可拖动圆圈会导致 dragenter 和 dragleave 事件,但 D3 可拖动圆圈不会。
即使我将 svg 用于我的解决方案,我也不知道如何获取拖动事件属性的详细信息(例如,导致事件的可拖动对象的详细信息)。
为什么 D3 不支持拖拽行为?
<!DOCTYPE html>
<meta charset="utf-8">
<!-- create a draggable svg rectangle -->
<div draggable="true">
<svg height="100" width="100">
<circle cx="50" cy="50" r="40" stroke="blue" stroke-width="3" fill="blue" />
</svg>
</div>
<div id="canvas"></div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
//create a canvas
var canvas = d3.select("#canvas")
.append("svg")
.attr("width", 800)
.attr("height", 600);
var draggableCircleData = [{x:100, y:100}];
// I can drag this circle but it does not cause the other circle to detect daragenter/ dragleave
var draggableCircle = canvas.append("circle")
.data(draggableCircleData)
.style("stroke", "gray")
.style("fill", "aliceblue")
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y;})
.attr("draggable","true")
.attr("r", 40)
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended));
// darg over circle. it detected the draging of the svg circle but not the D3 circle
var dragOverCircleData = [{x:300,y:100}];
var dragOverCircle = canvas.append("circle")
.data(dragOverCircleData)
.style("stroke", "gray")
.style("fill", "white")
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.attr("r", 40)
.on("dragenter", dragenter)
.on("dragleave",dragleave);
function dragleave(){
console.log("Darg leave event detected")
d3.select(this).style("fill", "white");
}
function dragenter(e1){
console.log("Darg enter event detected")
d3.select(this).style("fill", "blue");
}
function dragstarted(d) {
d3.select(this).raise().classed("active", true);
}
function dragged(d) {
//console.log("Item has been dragged.d: ",d)
d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y);
d3.select(this).attr("draggable","true");
}
function dragended(d) {
d3.select(this).classed("active", false);
}
</script>