javascript - 在同一元素上实现 shift click 和 click 功能

标签 javascript d3.js svg

我正在尝试在 d3 中实现点击事件,但我也希望可以选择在同一个 svg 元素上移动点击以触发不同的功能。如果我单击该元素,我希望它调用我的 clicked() 函数,但如果我移动单击该元素,我希望它将其填充样式更改为“steelblue”。我正在尝试:

.on("click", function(d){
      if (d3.event.shiftKey) {
          d3.select(this).style("fill", "steelblue");
      }
      clicked(d);
 })

但我只是从 d3 得到“Uncaught TypeError: t.getAttribute is not a function”,因为我假设我的 clicked() 函数没有被正确调用或传递参数。

如果我这样做:

.on("click", clicked);

我的 clicked() 函数运行良好,但我无法实现 shift click 功能。有谁知道让这两种功能都起作用的方法?我的点击功能本质上是一个缩放功能,顺便接受了数据 d。

最佳答案

If I do .on("click", clicked);my clicked() function works perfectly, but I have no way of implementing the shift click functionality.

为什么不呢?当然可以。只需检查 clicked 函数内的移位。

这是一个基本的演示:

var circles = d3.select("svg")
  .selectAll(null)
  .data(d3.range(5))
  .enter()
  .append("circle")
  .attr("r", 20)
  .attr("cy", 50)
  .attr("cx", function(d) {
    return 50 + 100 * d
  })
  .style("fill", "darkgray")
  .style("stroke", "black")
  .style("cursor", "pointer")
  .on("click", clicked);

function clicked() {
  if (d3.event.shiftKey) {
    d3.select(this).style("fill", "steelblue");
  }
  console.log("This is the clicked function")
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500" height="100"></svg>

为了完整起见,这是您的第一个代码段的问题:当您使用 selection.on 附加监听器时,

The specified listener will be evaluated for the element, being passed the current datum (d), the current index (i), and the current group (nodes), with this as the current DOM element (nodes[i]).

但是,在您的情况下,您只是将数据传递给 clicked 函数:

clicked(d);

因此,clicked 函数对 this 的引用不正确,它将是 window .检查以下代码段:

var circles = d3.select("svg")
  .selectAll(null)
  .data(d3.range(5))
  .enter()
  .append("circle")
  .attr("r", 20)
  .attr("cy", 50)
  .attr("cx", function(d) {
    return 50 + 100 * d
  })
  .style("fill", "darkgray")
  .style("stroke", "black")
  .style("cursor", "pointer")
  .on("click", function(d){
  	clicked(d)
  });

function clicked(datum) {
  console.log("The datum is: " + datum);
  console.log("'this' is: " + this)
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500" height="100"></svg>

一个简单的解决方法是保留对 this 的引用:

var circles = d3.select("svg")
  .selectAll(null)
  .data(d3.range(5))
  .enter()
  .append("circle")
  .attr("r", 20)
  .attr("cy", 50)
  .attr("cx", function(d) {
    return 50 + 100 * d
  })
  .style("fill", "darkgray")
  .style("stroke", "black")
  .style("cursor", "pointer")
  .on("click", function(d) {
    var self = this;
    clicked(d, self)
  });

function clicked(datum, thisElement) {
  console.log("The datum is: " + datum);
  console.log("'this' is: " + thisElement)
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500" height="100"></svg>

或使用 Function.prototype.call (如 @DavidKnipe 所建议):

var circles = d3.select("svg")
  .selectAll(null)
  .data(d3.range(5))
  .enter()
  .append("circle")
  .attr("r", 20)
  .attr("cy", 50)
  .attr("cx", function(d) {
    return 50 + 100 * d
  })
  .style("fill", "darkgray")
  .style("stroke", "black")
  .style("cursor", "pointer")
  .on("click", function(d) {
    clicked.call(this, d);
  });

function clicked(datum) {
  console.log("The datum is: " + datum);
  console.log("'this' is: " + this)
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="500" height="100"></svg>

关于javascript - 在同一元素上实现 shift click 和 click 功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48118536/

相关文章:

javascript - Fancybox 的烦恼

javascript - 修复 Dimple js 中分类轴中的类别

javascript - 设置 D3 svg.transition 从慢到快再到慢

javascript - 无法使用 JavaScript 设置 CSS 背景图像属性

html - 具有 3D 透视图的 CSS 网格作为图像叠加

javascript - JS事件不改变输入禁用属性

javascript - Canvas 中的中心图像

javascript - 使用 video.js 的完整视频背景

javascript - 在谷歌地图覆盖中使用 d3 绘制路径

javascript - 通过添加和拖动动态点(闪烁)进行多边形奇怪的重绘