phr*_*ist 5 javascript svg dom d3.js
我正在使用d3计时器为元素设置动画,我希望计时器在元素被删除时停止.这样做的简单方法是什么?
这是一个JS小提琴来说明我的问题.我该怎么替换这一行?
if (rect.empty()) {
Run Code Online (Sandbox Code Playgroud)
我意识到我可以通过改变它来使它工作:
if (d3.select("rect").empty()) {
Run Code Online (Sandbox Code Playgroud)
但是,如果我有很多rect元素或者重复使用相同的类,那么基于元素名称或类进行新的D3选择是一个问题.是否可以简单地刷新现有的D3选择以查看它是否已变空?
有两个 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> goneRun Code Online (Sandbox Code Playgroud)
<svg id="s">
<rect id="r"/>
</svg>Run Code Online (Sandbox Code Playgroud)
还有一些可用的属性可以提供对live HTMLCollection或NodeLists 的访问,这些属性可用于进一步的遍历:
ParentNode.children:居住 HTMLCollectionNode.childNodes:居住 NodeList但请注意,NodeLists 不能保证自己是活动的;你必须检查文档。以下两个方法将返回非活动NodeList,因此不能用于这些目的。
如果您需要他们提供的灵活性,您可以选择选项 2。
MutationObserver.MutationObserver每当您对 DOM 的更改感兴趣时,鲜为人知且被高度低估的接口就会派上用场。这是更复杂的方法,但具有更大的灵活性。
您创建一个新的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> goneRun Code Online (Sandbox Code Playgroud)
<svg id="s">
<rect id="r"/>
</svg>Run Code Online (Sandbox Code Playgroud)