Search code examples
javascriptdommutation-observers

Determining the indices of removedNodes in MutationRecord


I am working with MutationObserver API and want to correctly apply incoming MutationRecord to a copy of the tree I'm storing elsewhere. What puzzles me is removedNodes collection. When my observer is called and removedNodes is not empty, it means that the mutation has already taken place and the node has been removed from its' parent childNodes. Therefore, in order to determine its position in the child list before the mutation happened - to reflect that in my copy of the tree - I can inspect the previousSibling and nextSibling properties of the MutationRecord. But what if the removedNodes contains more than one element? Since the MutationRecord has only single occurrence of both previousSibling and nextSibling, the logical thing would be to think that removed nodes used to be between them. But is it what actually happens?

So, to state some single-sentences questions:

  1. is it safe to assume that if MutationRecord's removedNodes contains more than one node, then every node listed in that collection used to be between MutationRecord's previousSibling and nextSibling in the DOM tree before the mutation (removal) has happened?
  2. is it safe to assume that if multiple distant (i.e. not present in parent's childNodes collection at adjacent indices) children of a specified observed node got removed, that would result in multiple MutationRecords?
  3. if 1) is true, is it safe to assume that the order of the nodes in the array is the same order they used to be placed in their parent's childNodes?

Thanks in advance.


Solution

  • Is it safe to assume that if multiple distant (i.e. not present in parent's childNodes collection at adjacent indices) children of a specified observed node got removed, that would result in multiple MutationRecords?

    Yes. In general, every DOM method call results in one MutationRecord, and mutating multiple distant nodes requires multiple separate calls.

    Is it safe to assume that if MutationRecord's removedNodes contains more than one node, then every node listed in that collection used to be between MutationRecord's previousSibling and nextSibling in the DOM tree before the mutation (removal) has happened?

    Yes. It's rare that there's more than one node in addedNodes/removedNodes anyway. It can happen when

    • using a fragment as the new node when inserting/replacing
    • using replaceChildren(), .innerHTML= or .textContent= to remove all children
    • using surroundContent() to replace all nodes covered by the Range

    (no guarantee for exhaustiveness, but I've covered all calls to the respective algorithm from within the DOM spec)

    Everything else manipulates single nodes.

    Is it safe to assume that the order of the nodes in the array is the same order they used to be placed in their parent's childNodes?

    Yes.