我正在使用d3计时器为元素设置动画,我希望计时器在删除元素时停止。这样做的简单方法是什么?
这里有JS fiddle来说明我的问题。我该怎么用?
替换这一行? if (rect.empty()) {
我意识到我可以通过改变它来实现它:
if (d3.select("rect").empty()) {
但是,如果我有很多rect
元素或者重复使用相同的类,那么基于元素名称或类进行新的D3选择是一个问题。是否可以简单地刷新现有的D3选择以查看它是否已变空?
答案 0 :(得分:1)
有两种DOM功能可用于完成您所需的功能,完全不需要D3。它们都适合你,但复杂性和灵活性各不相同。
HTMLCollection
。 Document
和Element
接口都提供了类似的方法,可以根据指定的条件检索元素:
Document.getElementsByClassName()
和Element.getElementsByClassName()
Document.getElementsByTagName()
和Element.getElementsByTagName()
Document.getElementsByClassNameNS()
和Element.getElementsByClassNameNS()
所有这些方法都会返回 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;
还有一些可用的属性可以访问 实时 HTMLCollection
或NodeList
,可用于进一步遍历:< / p>
ParentNode.children
:直播 HTMLCollection
Node.childNodes
:直播 NodeList
但请注意,NodeList
不能保证直播;你必须检查文件。以下两种方法将返回 非实时 NodeList
,因此无法用于这些目的。
如果您需要他们提供的灵活性,您可以选择选项2.
MutationObserver
。当您对DOM的更改感兴趣时,鲜为人知且高度低估的MutationObserver
界面会派上用场。这是一种更复杂的方法,它可以提供更大的灵活性。
您创建一个新的MutationObserver
,提供一个回调,每次发生对DOM的相关更改时都会调用该回调。启动观察者时,您可以通过定义感兴趣的元素和子树以及传入MutationObserverInit
配置对象来指定相关的更改。在回调中,您可以随心所欲地对这些更改做出反应。
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;