如果用户单击d3.js中的回合,如何防止拖动? [英] How to prevent the drag if the user clicks the round in d3.js?

查看:40
本文介绍了如果用户单击d3.js中的回合,如何防止拖动?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有group元素,有circle和rect元素.用户可以拖动组元素,因此rect和circle元素都将移动.一切正常.但是,如果用户单击circle元素,则需要防止拖动. JS小提琴

I have group element it has circle and rect elements. User can drag the group element, so both rect and circle element will move. It is working fine. But I need to prevent the drag if the user clicks on the circle element. JS Fiddle

const x = 100;
var y = 100;

var grid = d3.select("#svg-area");

var g = grid.append("g")
  .attr("transform", `translate(${x},${y})`)
  .call(d3.drag()
    .on("drag", function() {
      var x1 = d3.event.x - 30;
      var y1 = d3.event.y - 10;
      d3.select(this).attr("transform", "translate(" +
        (x1) + "," + (y1) + ")")
    }));
newNode(g);

function newNode(g, text) {

  var textWid = 100;
  console.log('wid ', textWid);
  g.append("rect")
    .attr("class", "new-nodes")
    .attr("x", '10')
    .attr("y", '0')
    .attr("rx", '6')
    .attr("ry", '6')
    .attr("width", textWid)
    .attr("height", '35')
    .style("fill", "#8c259f")
    .style("stroke", "#222")
    .style("cursor", "move");

  g.append("circle")
    .attr("class", "new-nodes")
    .attr("cx", '10')
    .attr("cy", '17')
    .attr("r", '6')
    .style("fill", "#dedede")
    .style("stroke", "#b2b0b0")
    .style("cursor", "pointer")
    .on("click", function(d) {
      /*             d3.event.preventDefault();
                  d3.event.stopPropagation();
                   */
    });
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<svg id="svg-area" class="chart-area" width="500" height="500" pointer-events="all" style="cursor: crosshair; touch-action: none;">
</svg>

推荐答案

最简单的方法(最接近您的代码的一种方法)是将 on("click" 更改为 on(当再次释放鼠标按钮时,将记录一个"click"事件.在此之前,将明显记录一个"mousedown"事件.

The simplest way - the one closest to your code - is to change on("click" to on("mousedown". A "click" event is registered when the mouse button is released again. A "mousedown" event is clearly registered before that. And the mousedown event is the one that triggers "dragstart".

const x = 100;
var y = 100;

var grid = d3.select("#svg-area");

var g = grid.append("g")
  .attr("transform", `translate(${x},${y})`)
  .call(d3.drag()
    .on("drag", function() {
      var x1 = d3.event.x - 30;
      var y1 = d3.event.y - 10;
      d3.select(this).attr("transform", "translate(" +
        (x1) + "," + (y1) + ")")
    }));
newNode(g);

function newNode(g, text) {

  var textWid = 100;
  console.log('wid ', textWid);
  g.append("rect")
    .attr("class", "new-nodes")
    .attr("x", '10')
    .attr("y", '0')
    .attr("rx", '6')
    .attr("ry", '6')
    .attr("width", textWid)
    .attr("height", '35')
    .style("fill", "#8c259f")
    .style("stroke", "#222")
    .style("cursor", "move");

  g.append("circle")
    .attr("class", "new-nodes")
    .attr("cx", '10')
    .attr("cy", '17')
    .attr("r", '6')
    .style("fill", "#dedede")
    .style("stroke", "#b2b0b0")
    .style("cursor", "pointer")
    .on("mousedown", function(d) {
      d3.event.preventDefault();
      d3.event.stopPropagation();
    });
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<svg id="svg-area" class="chart-area" width="500" height="500" pointer-events="all" style="cursor: crosshair; touch-action: none;">
</svg>

或者,您可以将事件移至矩形并使用

Alternatively, you could just move the event to the rectangle and use d3.drag().container. Normally, d3.drag calculates the distance between the event and the parent element. Now, we need the grandparent, because the parent (the g element) is the thing we want to drag around.

我还更改了 g 元素以使用基准对象,因此您可以更轻松地移动它.

I also changed the g element to use a datum object, so you can more easily move it.

var grid = d3.select("#svg-area");

var g = grid.append("g")
  .datum({
    x: 100,
    y: 100
  })
  .attr("transform", function(d) {
    return `translate(${d.x},${d.y})`;
  });
newNode(g);

function newNode(g, text) {

  var textWid = 100;
  console.log('wid ', textWid);
  g.append("rect")
    .attr("class", "new-nodes")
    .attr("x", '10')
    .attr("y", '0')
    .attr("rx", '6')
    .attr("ry", '6')
    .attr("width", textWid)
    .attr("height", '35')
    .style("fill", "#8c259f")
    .style("stroke", "#222")
    .style("cursor", "move")
    .call(d3.drag()
      .container(grid.node())
      .on("drag", function() {
        d3.select(this.parentNode)
          .attr("transform", function(d) {
            d.x += d3.event.dx;
            d.y += d3.event.dy;
            return `translate(${d.x},${d.y})`;
          });
      }));

  g.append("circle")
    .attr("class", "new-nodes")
    .attr("cx", '10')
    .attr("cy", '17')
    .attr("r", '6')
    .style("fill", "#dedede")
    .style("stroke", "#b2b0b0")
    .style("cursor", "pointer");
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<svg id="svg-area" class="chart-area" width="500" height="500" pointer-events="all" style="cursor: crosshair; touch-action: none;">
</svg>

这篇关于如果用户单击d3.js中的回合,如何防止拖动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆