在d3.js中,如何在不进行新选择的情况下检查元素是否已被删除?

时间:2015-01-11 02:43:20

标签: javascript dom d3.js svg

我正在使用d3计时器为元素设置动画,我希望计时器在删除元素时停止。这样做的简单方法是什么?

这里有JS fiddle来说明我的问题。我该怎么用?

替换这一行?
  if (rect.empty()) {

我意识到我可以通过改变它来实现它:

  if (d3.select("rect").empty()) {

但是,如果我有很多rect元素或者重复使用相同的类,那么基于元素名称或类进行新的D3选择是一个问题。是否可以简单地刷新现有的D3选择以查看它是否已变空?

1 个答案:

答案 0 :(得分:1)

有两种DOM功能可用于完成您所需的功能,完全不需要D3。它们都适合你,但复杂性和灵活性各不相同。

1。使用直播 HTMLCollection

DocumentElement接口都提供了类似的方法,可以根据指定的条件检索元素:

所有这些方法都会返回 live HTMLCollection,这意味着即使首次检索,元素集合也会保持最新状态。您可以使用HTMLCollection.item().namedItem()查询集合来检查元素是否存在,或者,如果集合只包含一个元素,请查看.length



var svg = document.getElementById("s");

// This is a live HTMLCollection.
var rects = document.getElementsByTagName("rect");

console.log(rects.length);              // 1: <rect> in collection
svg.removeChild(rects.namedItem("r"));  // remove <rect#r>
console.log(rects.length);              // 0: <rect> gone
&#13;
<svg id="s">
  <rect id="r"/>
</svg>
&#13;
&#13;
&#13;

还有一些可用的属性可以访问 实时 HTMLCollectionNodeList,可用于进一步遍历:< / p>

但请注意,NodeList不能保证直播;你必须检查文件。以下两种方法将返回 非实时 NodeList,因此无法用于这些目的。

如果您需要他们提供的灵活性,您可以选择选项2.

2。使用MutationObserver

当您对DOM的更改感兴趣时,鲜为人知且高度低估的MutationObserver界面会派上用场。这是一种更复杂的方法,它可以提供更大的灵活性。

您创建一个新的MutationObserver,提供一个回调,每次发生对DOM的相关更改时都会调用该回调。启动观察者时,您可以通过定义感兴趣的元素和子树以及传入MutationObserverInit配置对象来指定相关的更改。在回调中,您可以随心所欲地对这些更改做出反应。

&#13;
&#13;
var svg = document.getElementById("s");
var rect = document.getElementById("r");

var observer = new MutationObserver(function(mutations) {
  // This callback will be called for all changes you configured it to listen to
  // and will provide information about every change in the array of 
  // MutationRecords. You can use this to filter and react to the changes you are
  // interested in by providing an approriate callback function. 
  var removed = mutations.filter(function(mutation) {
    return mutation.removedNodes.length > 0;
  });
  console.log(`Observed removal of ${removed.length} node(s).`)
})
 
// Listen for changes of the svg element to the child list only 
observer.observe(svg, { childList: true }); 

console.log("<rect> found: " + document.getElementById("r") != null);  // <rect> found
svg.removeChild(rect);                                                 // remove <rect>
console.log("<rect> found: " + document.getElementById("r") != null);  // <rect> gone
&#13;
<svg id="s">
  <rect id="r"/>
</svg>
&#13;
&#13;
&#13;