5

As the title says, I have an object, and i need all it's drag and click events. There was some discussion about this issue, but it mainly concerned the click and drag events. (and a reply fiddle didnt work properly)

I have a fiddle here of where I am at. When I drag, click is prevented, but when I click the dragstart and end events fire. I'd like them not to fire when I click, and I'd like click not to fire when I want to drag.

var drag = d3.behavior.drag()
  .origin(function(d){return d})
  .on('drag', function(d){
   d3.select(this).attr('cx', function(d){ return d.x += d3.event.dx });
   d3.select(this).attr('cy', function(d){ return d.y += d3.event.dy });   
   console.log('dragging');
})
.on('dragstart', function(d){
  d3.event.sourceEvent.stopPropagation()
  console.log('drag start');
})
.on('dragend', function(d){
  console.log('drag end');
})

// ..... 

 MySvgElementWith3DStuffOnIt.on('click', function(){
  if(d3.event.defaultPrevented) return;
  console.log('clicked');
});
Community
  • 1
  • 1
val
  • 729
  • 6
  • 19

2 Answers2

3

A small update of @thatOneGuy to use d3v4 drag module

https://jsfiddle.net/mhebrard/q5eL5qyv/

var drag = d3.drag()
    .on('drag', function(d){
    d3.select(this).attr('cx', function(d){ return d.x += d3.event.dx });
    d3.select(this).attr('cy', function(d){ return d.y += d3.event.dy });   
    console.log('dragging');
  })
  .on('start', function(d){
    console.log('drag start');
  })
  .on('end', function(d){
    console.log('drag end');
  })
Maxime Hebrard
  • 163
  • 1
  • 10
  • When I run this example and click on the circle, I still get all three drag events: drag start, dragging, and drag end. Running Chrome 64 – tgordon18 Feb 28 '18 at 18:38
2

Your example works as expected. See updated fiddle : https://jsfiddle.net/thatOneGuy/dd4nujxo/1/

I have put a few added console logs. When you drag this line :

if (d3.event.defaultPrevented) {console.log('return'); return};

Will stop the click event from firing. And when you only click, the dragstart and dragend get fired (as expected), but the drag doesn't. Which is why you put the code to move the circle inside the drag function. The whole thing works as expected :)

thatOneGuy
  • 9,977
  • 7
  • 48
  • 90
  • 2
    So i cannot click without triggering the dragstart and dragend at all? – val May 30 '16 at 20:58
  • I don't think so, what would be the problem with this ? – thatOneGuy May 30 '16 at 20:59
  • Iam writing a collaborative graph app, and when you click on the node it would add a new node, and when you drag it would lock it from others, also a grid would show up when you start dragging. And it looks annoying when I click on the node and the grid flashes up. Yeah it's nothing earth shattering, but it's still. – val May 30 '16 at 21:03
  • just place this code in the drag rather than drag start ? – thatOneGuy May 30 '16 at 21:04
  • 1
    That'll have to do. Won't be the most fancyfull solution, but it'll work. – val May 30 '16 at 21:05
  • That's all that matters ;) Won't be noticeable. But i think its the only solution. If you think about it what is classed by drag start ? Technically it's just a click right as once you start to move it, that changes to drag ? And drag end ? That'l be letting go of the click too ? So it all works as expected :) – thatOneGuy May 30 '16 at 21:07
  • When I run this example and click on the circle, I still get all three drag events: drag start, dragging, and drag end. Running Chrome 64 – tgordon18 Feb 28 '18 at 18:38
  • @val Did you get any solution for the first comment you made in this question? – Thilak Raj Jan 21 '21 at 12:58