删除调用事件侦听器的事件侦听器

时间:2018-05-26 19:58:11

标签: javascript d3.js addeventlistener

注意:有很多与删除事件侦听器相关的问题。 在简单的情况下,通过将匿名JS函数移动到命名函数然后调用具有指定名称的函数removeEventListener来解决它们。

e.g。

element.addEventListener("click", function(event){console.log("you clicked me");)})

转到

function youClickedMe(event) {console.log("you clicked me");}
element.addEventListener("click", youClickedMe)

然后在其他地方

element.removeEventListener("click", youClickedMe)

就我而言,它有点复杂。

  1. 我有一个需要传递的封闭变量
  2. 我的活动绑定了新的事件监听器
  3. 我想要创建捕获用户在单击鼠标左键(LMB)时所执行的操作,并且在DOM进入某个模式(按下按钮,切换布尔值)后鼠标移动到某个区域时< / p>

    到目前为止它工作得很好,请看小提琴:

    https://jsfiddle.net/SumNeuron/o1yu8oyt/

    但事件&#34; mousemove&#34;无论我尝试什么,都不会消失。

    此外,当我在混合中添加d3.zoom / d3.pan函数时,事情变得更糟......但这是一个单独的问题。

    有关如何删除此/添加的事件的任何想法?

2 个答案:

答案 0 :(得分:3)

正如the comments中已经解释的那样,您在这里引用了不同的功能。

如果出于某种原因,你无法重构你的代码和逻辑,你可以简单地将null作为D3选择的听众传递:

svg.on('mousedown', null)

顺便说一句,在D3代码中,使用D3方法比使用纯JS方法更方便。

以下是具有该更改的代码:

// toggle events with button
d3.select("button").on("click", toggle)
// for convenience
var svg = d3.select("svg")
// some external vars, could be closure vars...
var counter = 0;
var colors = ["red", "coral", "black", "white"]


function toggle(d, i) {

  var btn = d3.select(this)
  var activeQ = btn.classed("active")
  // toggle
  activeQ = !activeQ
  btn.classed("active", activeQ)

  // I have something like this in my code, and could be 
  // the route of the bug... but here for completeness
  var closedVar = "I can only be (easily) calculated here, but am needed in the event";

  if (activeQ) {
    // new toggle, start counter over
    counter = 0
    svg.on('mousedown', mousedown)
  } else {
    // remove the mouse down event
    svg.on('mousedown', null)
    // could clean up svg here, but for demo purposes leave it

    // maybe custom event to cleanup elsewhere?
    /* svg.dispatch("cleanup") */
  }

  // this function can use the local var closedVar
  // and be named in addEventListener
  function mousedown(event) {
    dropPoints(event, closedVar)
  }

}


function dropPoints(event, closedVar) {
  // want to only trigger on mouse down and move
  var pts = []
  svg.on('mousemove', mouseDownAndMove)
  svg.on('mouseup', function(event) {
    counter += 1;
    svg.on('mousemove', null)
  })


  /* svg.node().addEventListener('cleanup', function(event) {
    svg.node().removeEventListener('mousemove', mouseDownAndMove, true)
  }) */

  function mouseDownAndMove() {
    // event.which === 1 for mouse events ~might~ be left mouse button... at least in jQuery
    if (d3.event.which != 1) {
      return
    }

    var pt = d3.mouse(svg.node())

    svg.append("circle").attr("r", 3).attr("fill", colors[counter % (colors.length)])
      .attr("cx", pt[0])
      .attr("cy", pt[1])


  }
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<style>
  svg {
    width: 300px;
    height: 200px;
    background-color: blue;
  }
  
  .active {
    background-color: coral;
  }
</style>

<button>
Click to activate
</button>

<svg id="demo" width="500" height="500" style="background-color:blue;">
  
</svg>

答案 1 :(得分:1)

https://jsfiddle.net/jgv37zzk/

我试过移动一些东西。关键是removeEventsListener无效,因为您将useCapture标记设置为true,但未在addEventListener中设置它。

我不完全确定您尝试使用dropPoints函数做什么(因为,现在,只有绑定事件监听器),但是如果您提供更多上下文,我可以更新答案。