d3 click and drag event nesting

后端 未结 2 432
無奈伤痛
無奈伤痛 2020-12-08 17:45

I am nesting a lot of elements inside of a g element like so:


    
    
    ...



        
相关标签:
2条回答
  • 2020-12-08 18:33

    I have a similar sort of issue (http://jsfiddle.net/j8RZN/1/), except the suggested workaround does not seem to be helping.

    userBox.data([userBox]).call(d3.behavior.drag() //makes the box to move
    //titleBox.data([userBox]).call(d3.behavior.drag()  //does not make the box move
    .on("dragstart", function() {})
    .on("drag", function(d, i) {
    console.log('box being dragged');
    d.attr("transform", "translate(" + (d3.event.x) +  "," + (d3.event.y) + ")");
    })
    .on("dragend", function() {}));
    
    circleDrag.call(d3.behavior.drag()
    .on("dragstart", function() {})
    .on("drag", function(d, i) {
     d3.event.sourceEvent.stopPropagation();
     console.log('small rectangle being dragged');
    })
    .on("dragend", function() {}));
    
    0 讨论(0)
  • 2020-12-08 18:35

    An SVG <g> element does not have a size or area; it is a transparent container for all its descendants, and cannot intercept events for other elements (unless you are adding an event listener to be triggered during the 'capture phase').

    As a parent element, events bubble up to it; likely what you are seeing is that whatever event you're using to trigger the drag start (mousedown?) on the <rect> is also bubbling up to the <g> and starting a concurrent drag of that.

    To fix this, you want to stop your event from bubbling. In your event handler for the mousedown (or whatever) on the <rect> add:

    function startDrag(evt){
      // whatever your code is here
      evt.stopPropagation();
    }
    

    Without your actual code (or better, a pared-down test case) it's hard to know for sure, or help you further.


    Edit Here's a working version of your simple example: http://jsfiddle.net/ZrCQE/2/

    Specifically, apparently d3.event is not the event itself, but an object with a sourceEvent property that references the actual event.

    var dragGroup = d3.behavior.drag()
      .on('dragstart', function() {
        console.log('Start Dragging Group');
      }).on('drag', function(d, i) {
        d.x += d3.event.dx;
        d.y += d3.event.dy;
        d3.select(this).attr("transform", "translate("+d.x+","+d.y+")");
      });
    
    var dragCircle = d3.behavior.drag()
      .on('dragstart', function(){
        d3.event.sourceEvent.stopPropagation();
        console.log('Start Dragging Circle');
      })
      .on('drag', function(d,i){
        d.cx += d3.event.dx;
        d.cy += d3.event.dy;
        d3.select(this).attr('cx', d.cx).attr('cy', d.cy)
      });
    
    var svg = d3.select('body').append('svg').attr('viewBox','-50 -50 300 300');
    
    var g = svg.selectAll('g').data([{x:10,y:10}])
      .enter().append('g').call(dragGroup);
    
    g.append('rect').attr('width', 100).attr('height', 100);
    
    g.selectAll('circle').data([{cx: 90,cy:80}])
      .enter().append('circle')
        .attr('cx', function(d){ return d.cx })
        .attr('cy', function(d){ return d.cy })
        .attr('r', 30)
        .call(dragCircle);​
    
    0 讨论(0)
提交回复
热议问题