Javascript d3-单击时触发的拖动行为

Javascript d3-单击时触发的拖动行为,javascript,svg,d3.js,drag-and-drop,Javascript,Svg,D3.js,Drag And Drop,在我的svg容器中,我有一个带有矩形和文本的。当拖动这个组时,我想让这个组消失,然后在屏幕上拖动一个小矩形来表示对象。为了做到这一点,我使用了一个,当拖动开始时,我会使它可见。我让我的svg组被拖走了 你可以看到小提琴。 代码如下: function dragDiv2End(d) { console.log('ending'); var a = d3.select(this); a.attr('x', initial.x).attr('y', initial.y).

在我的svg容器中,我有一个带有矩形和文本的
。当拖动这个组时,我想让这个组消失,然后在屏幕上拖动一个小矩形来表示对象。为了做到这一点,我使用了一个
,当拖动开始时,我会使它可见。我让我的svg组被拖走了

你可以看到小提琴。 代码如下:

   function dragDiv2End(d) {
    console.log('ending');
    var a = d3.select(this);
    a.attr('x', initial.x).attr('y', initial.y).attr('width', initial.width).attr('height', initial.height);
    a.transition().style("opacity",1);
    d3.select('#dragid').style('visibility', 'hidden');

}

function dragDiv2Start(d) {
    d3.event.sourceEvent.stopPropagation();
    console.log('starting');
    var a = d3.select(this);
    initial = {x: a.attr('x'), y: a.attr('y'), width: a.attr('width'), height: a.attr('height')};
    a.attr('x', d3.mouse(this)[0])
    .attr('y', d3.mouse(this)[1]) .attr('width', 20)
    .attr('height', 20).style("opacity",0);

    var b = d3.select('#dragid');
    b.style({
        left: (parseInt(d3.mouse(this)[0])) + "px",
        top: d3.mouse(this)[1] + "px",
        border: "1px solid black",
        visibility: 'visible'

    });
}

function dragDiv2Move(d) {
    var b = d3.select(this);

    var a = d3.select('#dragid');
    a.transition().delay(50).style('opacity', 1);
    //console.log(d3.event.x, d3.event.y, a.style("right"));
    console.log(d3.mouse(this));
    a.style({
        left: (parseInt(d3.mouse(this)[0])) + "px",
        top: d3.mouse(this)[1] + "px"
    });
}

function doClick(d) {
    if (d3.event.defaultPrevented) return;
    console.log('clicked');
}
var initial = {};
var svg = d3.select('#div2').append('svg').attr('height', 300).attr('width', 300).style('border', 'solid 1px blue');

var g = svg.append('g').on('click', doClick);
g.append('rect').attr('x', 10).attr('y', 10).attr('width', 200).attr('height', 200).style('stroke', 'red').style('fill', 'white');
var text = g.append('text')
text.text('my test').attr('x', 50).attr('y', 50);

var dragDiv = d3.behavior.drag()
        .origin(Object)
        .on("drag", dragDivMove);

var dragDiv2 = d3.behavior.drag()
        .origin(Object)
        .on("dragstart", dragDiv2Start)
        .on("drag", dragDiv2Move)
        .on("dragend", dragDiv2End);
g.call(dragDiv2);
问题始于单击事件,该组也应收听该事件。当一个简单的点击发生时,我的svg对象消失了(拖动事件的行为),我得到了这种闪烁的效果

我理解为什么会发生这种情况,但这是非常不可取的,我正在努力找到解决这个问题的办法。要查看它的发生,只需单击和/或拖动红色矩形

我试着阻止事件传播,从拖动到单击都可以,但反过来不行


任何建议都将不胜感激。

我稍微整理了一下您的代码,并在这个SO代码片段中使用了“整洁”效果。要格式化synatx

首先,在启动和移动功能中。。我正在使一个变量对象保存
d3.mouse(this)
数据。(即,
var currentPosition={“x”:d3.鼠标(this)[0],“y”:d3.鼠标(this)[1]};

我正在做的是添加一个阈值并将其与距离关联。在将其包装到匿名函数中之后,我调用了dragStart方法。这允许我获取
This
实例以及
thresholdValue
,并将其绑定到我调用它的dragStart

var dragDiv2 = d3.behavior.drag()
  .origin(Object)
  .on("dragstart", function(arg) {
    console.log("anonymous function - arg: %o", arg);
    dragDiv2Start.bind(this.children[0], 5)();
  })
  .on("drag", dragDiv2Move)
  .on("dragend", dragDiv2End);
然而,
这实际上是元素
g
。。它没有设置任何属性,所以我得到了第一个子元素-
rect
,并将其绑定到dragStart方法

我创建了一个名为“threshold”的对象变量,该变量在dragStart函数中分配了
min.x
min.y
max.x
max.y
值。我还设置了一个名为
IsNeeded
的标志,指示dragMove函数是否应根据阈值进行检查,并有条件地返回或应用视觉更改。。如果
IsNeeded
为'still'true,dragEnd将简单地返回

我将您的视觉样式从dragStart移动到dragMove,我只在
阈值时运行它。IsRequired
设置为
false


示例代码段
函数dragDivMove(d){
var a=d3。选择(本);
风险值数据={
“事件”:{
“dx”:parseInt(d3.event.dx),
“dy”:parseInt(d3.event.dy)
},
选择:{
“right”:parseInt(a.style(“right”).replace(“px”),“”),
“top”:parseInt(a.style(“top”).replace(“px”),“”)
}
};
控制台日志(数据);
a、 风格({
“右”:(data.select.right-data.event.dx)+“px”,
“top”:(data.event.dy+data.select.top)+“px”
});
}
函数dragDiv2End(d){
console.log('ending');
var a=d3。选择(本);
变量b=d3。选择(“#dragid”);
a、 属性('x',首字母.x)
.attr('y',首字母.y)
.attr('width',初始.width)
.attr(“高度”,初始高度);
a、 过渡()样式(“不透明度”,1);
b、 样式(“可见性”、“隐藏”);
}
函数dragDiv2Start(阈值){
d3.event.sourceEvent.stopPropagation();
var a=d3。选择(本);
console.log('启动-此:%o,d3.select(此):%o,thresholdValue:%o',此,a,thresholdValue);
首字母={
“x”:parseInt(a.attr('x')。replace(“px”,0)),
“y”:parseInt(a.attr('y')。replace(“px”,0)),
“宽度”:parseInt(a.attr('width').replace('px',”),
“高度”:parseInt(a.attr('height')。替换(“px”,“高度”)
};
threshold.min={
“x”:初始.x-阈值,
“y”:初始.y-阈值
};
threshold.max={
“x”:初始.x+阈值,
“y”:初始.y+阈值
};
threshold.isNeeded=true;
var currentPosition={
“x”:d3.鼠标(此)[0],
“y”:d3.鼠标(此)[1]
};
日志(“当前:%o,初始:%o,阈值:%o”,当前位置,初始,阈值);
}
函数dragDiv2Move(d){
变量a=d3。选择(“#dragid”);
var b=d3。选择(本);
var currentPosition={
“x”:d3.鼠标(此)[0],
“y”:d3.鼠标(此)[1]
};
如果(阈值.isNeeded){
if(threshold.min.xcurrentPosition.x | | threshold.max.y>currentPosition.y){
threshold.isNeeded=false;
b、 属性('x',currentPosition.x);
b、 属性('y',当前位置.y);
b、 属性(“宽度”,20);
b、 attr('高度',20);
b、 样式(“不透明度”,0);
a、 风格({
“左”:currentPosition.x+“px”,
“顶部”:currentPosition.y+“px”,
“边框”:“1px纯黑”,
“可见性”:“可见”
});
}否则{
返回;
}
}
控制台日志(当前位置);
a、 transition().延迟(50).样式('opacity',1);
a、 风格({
“左”:currentPosition.x+“px”,
“顶部”:currentPosition.y+“px”
});
}
函数doClick(d){
if(d3.event.defaultPrevented)返回;
console.log('clicked');
}
var initial={},
阈值={
“min”:{
“x”:0,
“y”:0
},
“最大值”:{
“x”:0,
“y”:0
},
“isNeeded”:正确
};
var svg=d3.select('#div2')。append('svg')。attr('height',300)。attr('width',300)。style('border','solid 1px blue');
var g=svg.append('g')。on('click',doClick);
g、 追加('rect').attr('x',10.).attr('y',10.).attr('width',200.).attr('height',200.).style('stroke','red').style('fill','white');
var text=g.append('text')
text.text('my test').attr('x',50).attr('y',50);
var dragDiv=d3.behavior.drag()
.原点(对象)
。打开(“拖动”,拖动或移动);
var dragDiv2=d3.behavior.drag()
.原点(对象)
.on(“dragstart”,函数(){
dragDiv2Start.bind(this.children[0],5)();
})