Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
555 views
in Technique[技术] by (71.8m points)

javascript - 突变观察者仅在父元素上触发(Mutation Observer only triggering on Parent Element)

I'm trying to use a MutationObserver to watch for removed nodes in an application library, but it appears that when a parent is removed (or replaced), it doesn't trigger the callback for all of the child elements.(我正在尝试使用MutationObserver监视应用程序库中已删除的节点,但看来当父级被删除(或替换)时,它不会触发所有子元素的回调。)

<button class="RemoveListButton">Remove List</button> <div class="Container"> <ul class="ShoppingList"> <li class="Item">Pasta</li> <li class="Item">Chips</li> <li class="Item">Salsa</li> </ul> </div> const removeWatcher = new MutationObserver(mutationList => { const removedNodes = mutationList.flatMap(m => [...m.removedNodes]) console.log('Removing', removedNodes) }) const container = document.querySelector('.Container') removeWatcher.observe(container, { subtree: true, childList: true }) /* additional javascript to remove elements on click */ See JSFiddle https://jsfiddle.net/eq4ahsvc/3/(参见JSFiddle https://jsfiddle.net/eq4ahsvc/3/) In the example, when I remove an individual list item (by clicking on it), I see in the console that the element was removed and seen by the Mutation Observer.(在该示例中,当我删除单个列表项(通过单击它)时,我在控制台中看到该元素已被删除,并且被突变观察者看到。) However, when I remove the entire list, the Mutation Observer callback is only triggered for the parent, and not the individual child elements.(但是,当我删除整个列表时,只会为父级而不是单个子元素触发Mutation Observer回调。) Is there a way to configure this behavior?(有没有一种方法可以配置此行为?) Ideally every element would trigger the MutationObserver callback, such that when removing the list, I see the trigger for removing the list, and the trigger for removing each of the child elements.(理想情况下,每个元素都将触发MutationObserver回调,这样,在删除列表时,我会看到删除列表的触发器以及删除每个子元素的触发器。)   ask by JRJurman translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The child elements are not removed from their parent, so there's no remove event to observe.(子元素不会从其父元素中删除,因此没有观察到的remove事件。)

See:(看到:) const ul = document.querySelector('ul'); const li = ul.children[0]; ul.remove(); console.log(li.parentElement); <button class="RemoveListButton">Remove List</button> <div class="Container"> <ul class="ShoppingList"> <li class="Item">Pasta</li> <li class="Item">Chips</li> <li class="Item">Salsa</li> </ul> </div> As you can see, the <li> s still have a parent element of the .ShoppingList , because the .ShoppingList was removed from its container, but the individual <li> s were not removed from the .ShoppingList .(如您所见, <li>仍然具有.ShoppingList的父元素,因为.ShoppingList已从其容器中删除,但各个<li>并未从.ShoppingList删除。) If you wanted to see events for each removed <li> , you'd have to iterate over and remove them explicitly in addition to removing the .ShoppingList :(如果要查看每个删除的<li>事件,除了删除.ShoppingList之外,还必须遍历并显式删除它们:) const removeWatcher = new MutationObserver(mutationList => { const removedNodes = mutationList.flatMap(m => [...m.removedNodes]) console.log('Removing', removedNodes) }) const container = document.querySelector('.Container') removeWatcher.observe(container, { subtree: true, childList: true }) const button = document.querySelector('.RemoveListButton') button.onclick = () => { document.querySelectorAll('.ShoppingList > li').forEach(li => li.remove()); document.querySelector('.ShoppingList').remove() } const listItems = document.querySelectorAll('.Item') listItems.forEach(item => item.onclick = () => { event.target.remove() }) <button class="RemoveListButton">Remove List</button> <div class="Container"> <ul class="ShoppingList"> <li class="Item">Pasta</li> <li class="Item">Chips</li> <li class="Item">Salsa</li> </ul> </div> For what you want, either do that, or recursively flatten all children of every item in the removedNodes array inside the observer callback.(为此,您可以执行此操作,也可以递归地将观察者回调内removedNodes数组中每个项目的所有子项展平。)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...