Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 当我在D3中触发事件的过程中删除相应的元素时,如何删除元素的事件侦听器?_Javascript_D3.js - Fatal编程技术网

Javascript 当我在D3中触发事件的过程中删除相应的元素时,如何删除元素的事件侦听器?

Javascript 当我在D3中触发事件的过程中删除相应的元素时,如何删除元素的事件侦听器?,javascript,d3.js,Javascript,D3.js,当我在D3中触发事件的过程中删除相应的元素时,如何删除元素的事件侦听器 现在,在我调用.remove()之后,事件似乎仍在继续 例如,我有一个监听mousedown的事件监听器,如果我一直在mousedown并使用键盘删除相应的元素,mousedown事件仍然会保留。这是预期的吗 更具体地说,我处理的是我的元素调用的d3.drag()函数 如果是,是否有一种方法可以一次清除所有这些文件,或者我需要手动删除它们?如何消除挥之不去的事件 以下是要复制的链接: 尝试拖动矩形,不要向下释放鼠标。按下一个

当我在D3中触发事件的过程中删除相应的元素时,如何删除元素的事件侦听器

现在,在我调用
.remove()
之后,事件似乎仍在继续

例如,我有一个监听mousedown的事件监听器,如果我一直在mousedown并使用键盘删除相应的元素,mousedown事件仍然会保留。这是预期的吗

更具体地说,我处理的是我的元素调用的d3.drag()函数

如果是,是否有一种方法可以一次清除所有这些文件,或者我需要手动删除它们?如何消除挥之不去的事件

以下是要复制的链接:

尝试拖动矩形,不要向下释放鼠标。按下一个键,矩形将消失,但当您移动鼠标时(仍然是鼠标向下),您将看到控制台仍在打印“拖动”

更新

@Gerardo Furtado下面的答案仍然是一个解决方法,即使用if语句使所有触发的函数返回。换句话说,如果用户不在幕后释放mousedown,这个拖动功能仍然会永远被触发,只是因为他们都会返回,所以他们什么都不会做。这仍然是对资源的完全浪费


我能想到的导致这个问题的唯一解释是,D3只能在事件侦听器不再处于活动状态时删除它,即它必须等待用户释放。因此,我需要一种方法来释放所有触发的用户交互。

这是一个有趣的问题,尽管我必须承认,我从未在实际应用程序中遇到过这个问题。发生这种情况的原因可以在D3的拖动实现的内部工作中找到

首先,值得一提的是,如果从DOM树中删除元素,那么在对指针事件执行命中测试时,它将不再成为目标。因此,不再执行在该元素上注册的事件侦听器。这是人们所期望的行为,也是您感到困惑的原因,因为在JSFIDLE中,即使成功删除了元素,监听器似乎也会执行

要了解正在发生的事情,您必须深入研究
d3.drag()
的用法。初始化时,拖动行为会在选择的元素上显示各种事件处理程序:

function drag(selection) {
  selection
      .on("mousedown.drag", mousedowned)
  //...
}
此侦听
mousedown
事件的处理程序不会在相应元素上触发此类事件之前设置其余的拖动行为。一旦拖动行为的元素接收到
mousedown
事件,将执行内部处理程序:

function mousedowned() {
  //...
  select(event.view).on("mousemove.drag", mousemoved, true).on("mouseup.drag", mouseupped, true);
  //...
}
在这个处理程序中,一个
“mousemove.drag”
和一个
“mouseup.drag”
侦听器在
事件视图上注册。
MouseEvent
的此属性从界面继承,至少在浏览器中指向事件发生的
窗口
对象。d3 drag使用全局
窗口
上的这些拖动处理程序来执行其工作。那些处理者要为你所目睹的看似混乱的行为负责。我们很快就会谈到这一点,首先让我们检查侦听器随后是如何被删除的

当拖动手势最终通过触发
mouseup
事件而结束时,这些处理程序将从函数
mouseupped()
中的
窗口
对象中删除:

现在,让我们再看看您的代码。即使您删除了由
keydown
事件触发的拖动行为的目标,
窗口上的上述处理程序仍然存在,因为您一直按住鼠标按钮,从而抑制要触发的
mouseup
事件。因此,
mouseupped()
处理程序尚未执行。这将使拖动行为保持活动状态,因为
mousemove
事件仍由拖动的内部处理程序在
窗口上捕获。此外,这些内部处理程序还将继续委托给您自己的
拖动的
处理程序,从而导致您看到的控制台输出

正如在这篇文章的开头所提到的,我从未见过这会给现实世界带来任何麻烦。如果仍要避免此行为,可以在删除目标后删除内部处理程序:

d3.select(window).on("keydown", function() {
    d3.select(".draggable-rect").remove();
    d3.select(d3.event.view)          // Remove global (internal) drag handlers 
      .on("mousemove.drag", null)
      .on("mouseup.drag", null);
})
当涉及到摆弄某些库的内部工作时,总是这样,你必须小心不要破坏其他东西,并记住,这有可能会在将来的D3版本中悄无声息地破坏

请查看此工作演示:

d3.select(“svg”).append(“rect”).attr(“class”,“draggable rect”);
d3.选择(窗口).on(“向下键”,函数(){
d3.选择(“.draggable rect”).remove();
d3.选择(d3.事件.视图)
.on(“mousemove.drag”,null)
.on(“mouseup.drag”,null);
})
d3.选择(“.draggable rect”)
.call(d3.drag().on(“开始”,dragstarted)
.打开(“拖动”,拖动)
。在(“结束”,dragended));
函数dragstarted(d){
d3.选择(this).raise().classed(“活动”,true);
}
函数(d){
console.log(“拖动”)
d3.选择(this.attr(“x”,d3.event.x-40).attr(“y”,d3.event.y-40);
}
函数d(d){
d3.选择(此).classed(“活动”,false);
}
。测试区域{
宽度:400px;
高度:400px;
边框:1px纯黑;
}
svg{
宽度:400px;
高度:400px;
}
.可拖动矩形{
宽度:80px;
高度:80px;
填充:绿色;
}


回调可能会继续运行,但不再有侦听器(afaik)。请使用代码片段(
按钮)重现问题,这样我们就可以看到发生了什么。@GerardoFurtado是回调函数。@t
d3.select(window).on("keydown", function() {
    d3.select(".draggable-rect").remove();
    d3.select(d3.event.view)          // Remove global (internal) drag handlers 
      .on("mousemove.drag", null)
      .on("mouseup.drag", null);
})