我使用一个d3计时器来动画一个元素,当元素被移除时,我希望计时器停止。做这件事的简单方法是什么?
这里有一个JS小提琴来说明我的问题。我该用什么来代替这条线?
if (rect.empty()) {
我意识到我可以把它变成这样:
if (d3.select("rect").empty()) {
但是,如果我有大量的D3元素或者经常重用相同的类,那么根据元素名称或类进行新的rect
选择是一个问题。是否可以简单地刷新现有的D3选择,以查看它是否已变为空?
发布于 2016-11-07 13:20:52
有两个DOM特性可用于完成您正在寻找的内容,这将根本不需要D3。它们都会为您工作,但在复杂性和灵活性方面会有所不同。
1.使用live 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
<svg id="s">
<rect id="r"/>
</svg>
还有一些属性可以提供对live HTMLCollection
s或NodeList
s的访问,这些属性可用于进一步遍历:
ParentNode.children
:live HTMLCollection
Node.childNodes
:live NodeList
但是,请注意,不能保证NodeList
是独立存在的;您必须检查文档。以下两个方法将返回一个non-liveNodeList
,因此不能用于这些目的。
如果您需要他们提供的灵活性,您可以选择备选方案2。
2.使用MutationObserver
。
每当您对DOM的更改感兴趣时,鲜为人知和高度低估的MutationObserver
接口就会派上用场。不过,这是一种更复杂的方法,它允许更多的灵活性。
您将创建一个新的MutationObserver
,提供一个回调,每次发生DOM的相关更改时都会调用该回调。在启动观察者时,可以通过定义感兴趣的元素-and子树和传入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
<svg id="s">
<rect id="r"/>
</svg>
https://stackoverflow.com/questions/27883455
复制相似问题