可能的d3错误:dragend触发而没有任何拖动事件

问题描述 投票:3回答:2

我正在使用d3js拖动行为。这是demo。当我单击元素时,将触发“拖动”和“拖动”事件。即使我不尝试拖动它们,事件仍然会触发。我想在点击项目时调用其他函数,并且仅当我拖动项目时才触发拖动事件。因此,如何在此处分离出拖动事件和单击事件。

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 + ")");
 }
d3.js dom svg drag-and-drop dom-events
2个回答
2
投票

编辑3

这是对您的替代答案的回复。您在此处张贴的小提琴无法准确反映我试图描述的解决方案。我更新了。下面的小提琴应该是区分click和“ true”拖尾事件的正确方法的示例。请注意,我们没有使用“点击”处理程序。

http://jsfiddle.net/V92CF/

编辑2

[好吧,我将此问题发布到了d3谷歌论坛上,并得到了杰森·戴维斯(Jason Davies)的回答。我们看到的行为是预期的行为,不是错误。 “点击”仅被视为平凡(移动0像素)拖动,但仍然是拖动。 d3的创建者Mike在这里解释了原因:

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

因此,解决问题的正确方法是我之前所说的一种破解方法:您需要检测是否在Dragend处理程序内进行了实际的移动,然后才触发逻辑。

编辑

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

以下原始帖子

这里唯一的问题是使用alert。我将所有的alert更改为console.log,并且可以正常工作:

http://jsfiddle.net/TrWw3/

我认为它与警报混淆了,因为一旦您开始拖动,它将触发警报框,这需要您将其关闭。但是,当您关闭它时,鼠标已经跳了起来,有关此过程的某些事情使事情变得混乱了。

无论如何,打开chrome或firefox js控制台的console.log会很好地解决您的问题。


1
投票

由于我没有得到预期的答案,所以我要提供一个替代方法来实现这一目标。希望有人对此有所回答。并再次感谢@jonah。如果您在这方面有任何更新,请告诉我。这是Alternate way要做的。

  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 + ")");
    }
© www.soinside.com 2019 - 2024. All rights reserved.