防止动画期间的点击事件

时间:2018-12-19 22:48:03

标签: javascript d3.js

在下面的代码中,我制作了三个按钮,它们在您单击em时可以移动,但是如果在动画过程中单击em,它仍然可以触发update()事件。

有没有办法确保您在动画过程中不能按下按钮?

我尝试设置标志以阻止更新,但是我想不出一种方法来使它工作而不必双击按钮。

另一种选择是使用setTimeout,但是我不确定这是否会引起一些同步问题。

代码如下:

update(new Date().getFullYear(), 0);

function update(year, speed) {

	var t = d3.transition().duration(speed);

	var svg = d3.select("svg");

	var result = [(year -1).toString(), (year).toString(), (year +1).toString()];

	var buttons = svg.selectAll(".button").data(result, d => d)

	buttons.exit().transition(t)
		.attr("x", d => +d > year ? 240 : -60)
		.style("opacity", 0)
		.remove()

	buttons.enter().append("rect")
		.attr("class", "button")
		.style("opacity", 0)
		.attr("width", 70)
		.attr("height", 25)
		.attr("y", 15)
		.attr("x", d => +d > year ? 240 : -60)
		.attr("value", d => d)
		.merge(buttons)
	.transition(t)
		.style("opacity", 1)
		.attr("x", (_, i) => 15 + 75 * i)
		.attr("fill", d => +d == year ? "#666" : "#ddd")

	var onclick = d3.selectAll(".button")
		.on("click", function() {
			update(+(d3.select(this).attr("value")), 750)
		})
}
body {
	padding-top: 35px;
	margin: auto;
	width: 550px;
	font: 12px monospace;
}
svg {
	width: 250px;
	height: 55px;
}
<meta charset="utf-8">
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg class="buttons"></svg>

2 个答案:

答案 0 :(得分:1)

看起来speed是过渡的总持续时间。您可以在update函数外部使用一个变量,该变量使gate保持update

let inTransition = false;

update(new Date().getFullYear(), 0);

function update(year, speed) {

    if (!inTransition) {

         inTransition = true;

         setTimeout(() => { inTransition = false; }, speed);

          var t = d3.transition().duration(speed);

          var svg = d3.select("svg");

          var result = [(year -1).toString(), (year).toString(), (year +1).toString()];

          var buttons = svg.selectAll(".button").data(result, d => d)

          buttons.exit().transition(t)
            .attr("x", d => +d > year ? 240 : -60)
            .style("opacity", 0)
            .remove()

          buttons.enter().append("rect")
            .attr("class", "button")
            .style("opacity", 0)
            .attr("width", 70)
            .attr("height", 25)
            .attr("y", 15)
            .attr("x", d => +d > year ? 240 : -60)
            .attr("value", d => d)
            .merge(buttons)
          .transition(t)
            .style("opacity", 1)
            .attr("x", (_, i) => 15 + 75 * i)
            .attr("fill", d => +d == year ? "#666" : "#ddd")

          var onclick = d3.selectAll(".button")
            .on("click", function() {
              update(+(d3.select(this).attr("value")), 750)
            })
    }
}
body {
	padding-top: 35px;
	margin: auto;
	width: 550px;
	font: 12px monospace;
}
svg {
	width: 250px;
	height: 55px;
}
<meta charset="utf-8">
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg class="buttons"></svg>

答案 1 :(得分:1)

d3有相应的事件。 (参考:https://github.com/d3/d3-transition/blob/master/README.md#transition_on

您必须在开始过渡时禁用指针事件,然后在结束过渡时启用指针事件。 (此外,您还可以在开始和结束时绑定和取消绑定Click事件)

签出:

update(new Date().getFullYear(), 0);

function update(year, speed) {

  var t = d3.transition().duration(speed);

  var svg = d3.select("svg");

  var result = [(year - 1).toString(), (year).toString(), (year + 1).toString()];

  var buttons = svg.selectAll(".button").data(result, d => d)

  buttons.exit().transition(t)
    .attr("x", d => +d > year ? 240 : -60)
    .style("opacity", 0)
    .remove()

  buttons.enter().append("rect")
    .attr("class", "button")
    .style("opacity", 0)
    .attr("width", 70)
    .attr("height", 25)
    .attr("y", 15)
    .attr("x", d => +d > year ? 240 : -60)
    .attr("value", d => d)
    .merge(buttons)
    .transition(t)
    .on("start", function() {
      document.getElementById("buttons").style.pointerEvents = "none";
    })
    .on("end", function() {
      document.getElementById("buttons").style.pointerEvents = "all";
    })
    .style("opacity", 1)
    .attr("x", (_, i) => 15 + 75 * i)
    .attr("fill", d => +d == year ? "#666" : "#ddd")

  var onclick = d3.selectAll(".button")
    .on("click", function() {
      update(+(d3.select(this).attr("value")), 750)
    })
}
body {
  padding-top: 35px;
  margin: auto;
  width: 550px;
  font: 12px monospace;
}

svg {
  width: 250px;
  height: 55px;
}
<meta charset="utf-8">
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg id="buttons" class="buttons"></svg>