Let’s imagine the situation: you receive a bug in a component of application you don’t familiar with. The issue is connected with some strange DOM behavior. For example: some part is removed from the document, some incorrect classes applied. The code of the component is quite huge and it will take a while to find all the places, where these modifications can be performed, set breakpoints and try so see, whether this part of code is involved in the issue or not.
The good news that you can simplify your work a little bit. You can ask browser to help to find the line of code, which is causing unpredicted side effect. I’ll describe three way to achive this. The code will be the same for all three types, so I’ll put it here:
Basically this is a regular HTML mark up. There is
div#toRemove which receives additional class and then is being removed from the document after 5 seconds. And the main goal is to get the breakpoint exactly on this line before the node is deleted or receives additional class.
1. Use Chrome Developer tools
In Chrome developer tools this functionality has already been integrated into user interface, so you don’t need any specific knowledge to use it. Just open DOM node’s context menu on select one of the required options:
- Subtree modifications – will listen to any subtree modifications, like appending or removal of the nodes. But it will skip attribute modifications;
- Node removal – will only trigger when particular node is removed;
- Attribute modifications – will only trigger when particular node receives some attribute modifications (not working for subtrees);
That’s it. If you try one of these approaches – you’ll be paused in debugger with appropriate line highlighted.
2. Use DOM Mutation events
There is quite handy functionality currently supported by browsers: DOM Mutation Events (use this link to see full list of supported events).
Important: this functionality should not be used for production code, there are issues with cross-browser support, performance and the fact, that it’s deprecated and can be removed at any time.
To use this approach you need to execute something like this:
In this code you are attaching an event listener to an entire document. This event will trigger on any subtree modification. After attaching this event all you need is to try to reproduce situation which is causing the unexpected behavior and wait for
debugger; breakpoint to hit. Then using Stack Trace find the code, which triggers this event. Unfortunately it works only in Chrome and Firefox. Not sure why, but in IE11 and Edge – the function, which triggers the event does not appear in Stack Trace, which is making this code quite useless.
3. Use Mutation Observer
Mutation Observer is a functionality, which should fully replace Mutation Events at some point. The good thing, that it’s already been implemented in the majority of browsers. The bad thing – this functionality is asynchronous. So you cannot use regular stack traces. In Chrome a support for asynchronous stack traces already exists (refer to the screenshot below), but in other browsers unfortunately it’s not implemented yet.
All you need is to create a
MutationObserver object and bypass a callback function, which should be used. Then, using this observer you need to start observing DOM modifications, using
observe function. The first argument is the DOM node, the second is a set of options (you can find the full list of supported properties on the MDN page, provided earlier). Here is my code sample:
This code will work in Firefox and Edge, but it’s not very informative, because as I’ve mentioned earlier – in the Stack Trace you’ll see only one function. The source of the change will still be hidden from you. Hopefully Mozilla and Microsoft will integrate this amazing feature in their browsers soon.
Tested in browsers:
- Firefox 40.0.3;
- Chrome 46.0.2490.13 beta-m (64-bit)
- Edge 20.10240.16384.0