可能的d3 Bug:在没有任何拖拽事件的情况下拖拽触发



我使用d3js拖动行为。这是一个演示。当我点击元素时,'drag'和'dragend'事件被触发。即使我不试图拖动它们,事件仍然会触发。我想在点击项目时调用其他函数。拖拽事件应该只在拖拽项目时触发。那么如何把拖拽事件和点击事件分开呢

function onDragDrop(dragHandler, dropHandler) {
    var drag = d3.behavior.drag();
drag.on("drag", dragHandler)
.on("dragend", dropHandler);
return drag;
}
  var d = [{ x: 20, y: 20 }];
    var g = d3.select("body").select("svg").data(d).append("g").attr("transform", function (d) { return        "translate(" + d.x + "," + d.y + ")"; })
     .call(onDragDrop(dragmove, dropHandler));
g.append("rect")
.attr("width", 40)
.attr("height", 40)
.attr("stroke", "red")
.attr("fill","transparent")
.attr("x", "20" )
.attr("y", "20")
g.append("text")
.text("Any Text")
.attr("x", "20" )
.attr("y", "20")
function dropHandler(d) {
    alert('dropped');
}
function dragmove(d) {
  alert('dragged');
  d.x += d3.event.dx;
  d.y += d3.event.dy;
  d3.select(this).attr("transform", "translate(" + d.x + "," + d.y + ")");
 }

EDIT 3

这是对你的备用答案帖子的回应。你在那里张贴的提琴并不能准确地反映我试图描述的解决方案。我更新了。下面的例子应该是区分点击和"真正"拖放事件的正确方法。注意,我们没有使用"click"处理程序。

http://jsfiddle.net/V92CF/

编辑2

好吧,我把这个问题贴在d3谷歌组,并得到了杰森戴维斯的回答。我们看到的行为是预期的行为,它不是一个bug。"点击"只是被认为是微不足道的(移动了0个像素)拖动,但它仍然是一个拖动。d3的创造者Mike在这里解释了原因:

https://github.com/mbostock/d3/pull/368

因此,您的问题的正确解决方案是我之前描述的一个hack:您需要检测是否在您的dragend处理程序中实际进行了移动,然后仅在有时触发您的逻辑。

编辑

请注意我下面的原始答案是错误的。我误解了这个问题。下面的评论和我对OP的编辑应该澄清

下面的原文

这里唯一的问题是使用alert。我把所有的alert s改为console.log s,它工作得很好:

http://jsfiddle.net/TrWw3/

我认为它和警报混淆了因为一旦你开始拖拽,它就会触发警报框,这需要你关闭它。但是当你关闭它的时候,鼠标已经跳跃了,这个过程中的一些东西把事情搞砸了。

无论如何,console.log与chrome或firefox js控制台打开会解决你很好。

因为我没有得到预期的答案,所以我给出了一个替代方案来实现这一点。希望有人能给出答案。再次感谢@jonah。如果你在这方面发现任何更新,请告诉我。这是另一种方法。

  var d = [{ x: 20, y: 20 }];
  var flag = false;
  var g = d3.select("svg").data(d).append("rect")
    .attr("width", 40)
    .attr("height", 40)
    .attr("stroke", "red")
    .attr("fill","transparent")
    .attr("x", "20" )
    .attr("y", "20")
    .on("click", function(){ console.log('clicked');})
   .call(d3.behavior.drag().on("drag", dragHandler).on("dragend", dropHandler))
 function dropHandler(d) {
       if(flag){
            console.log('dropped');
            flag = false;
        }}
 function dragHandler(d) {
        flag = true;
        console.log('dragged');
        d.x += d3.event.dx;
        d.y += d3.event.dy;
        d3.select(this).attr("transform", "translate(" + d.x + "," + d.y + ")");
    }

相关内容

最新更新