丢失事件处理程序并在切换图层后重新添加事件处理程序时出现问题

时间:2017-03-10 19:32:58

标签: javascript d3.js svg

我使用以下代码将svg组移到前面:

d3.selection.prototype.moveInFrontOf = function () {
    return this.each(function () {
        this[0].parentNode.append(this[0]);
    });
};

这有效地提升了这一层。我坚持使用d3 v3。如果我能够使用d3 v4,那么我将使用新的raise()功能。事件处理程序正在迷失,我很难将它们添加回来。这是我用来将点击处理程序添加回路径的代码:

d3.select(overlay).on('click', "javascript:alert('test')" );

JS似乎是有效的但是当我检查元素检查器中的path元素时,单击处理程序没有被添加。我想我已经读过,当使用d3动态更改组顺序时,事件处理程序会丢失。尝试添加事件处理程序还有问题吗?或者是否应该使用特殊技术?或者我的代码出了什么问题?作为第一步,我能做出更简单的模式吗?

1 个答案:

答案 0 :(得分:1)

由于您未使用D3 v4(以及方便的raise()lower()功能),因此您必须创建一种解决方法。使用D3 v3有不同的方法(其中一些非常hacky,其中一些更优雅)。

这个依赖于对DOM数组进行排序。这样,既然您只是对数组中的元素进行排序,那么您就不会丢失任何事件处理程序。

在此演示中,事件处理程序是一个mouseover事件,可将颜色更改为红色。单击圆圈时,可以通过对DOM数组进行排序来启动它:



var data = d3.range(4).map(d => ({
  clicked: false
}))

var circles = d3.selectAll("circle")
  .data(data);

circles.on("mouseover", function() {
  d3.select(this).attr("fill", "red")
}).on("mouseout", function() {
  d3.select(this).attr("fill", "blue")
});

circles.on("click", function() {
  d3.select(this).datum().clicked = true;
  circles.sort(function(a, b) {
    return d3.ascending(a.clicked, b.clicked)
  });
  d3.select(this).datum().clicked = false;
});

<script src="https://d3js.org/d3.v3.js"></script>
<svg width="400" height=200>
  <circle cy="100" cx="80" r="60" fill="blue" stroke-width="3" stroke="black"></circle>
  <circle cy="100" cx="160" r="60" fill="blue" stroke-width="3" stroke="black"></circle>
  <circle cy="100" cx="240" r="60" fill="blue" stroke-width="3" stroke="black"></circle>
  <circle cy="100" cx="320" r="60" fill="blue" stroke-width="3" stroke="black"></circle>
</svg>
&#13;
&#13;
&#13;