Why is the style of the element changed so often?

Why are DOM properties missing?

Who is responsible for the lost DOM??

The strange DOM that appears is human or ghost ????

Behind all this is the distortion of human nature or the collapse of morality ?????

Is the Bug that writes unintentionally or someone intentionally ??????

Let’s follow the camera as we explore the ever-changing DOM.

The origin of

Recently, WHEN I was working on a project, I encountered a problem:

Just a page written a long time ago, and the code inside is messy. My job was to fit the height of the page to the screen. There are several

Because the code is messy, it’s hard to figure out which code is messing with it.

Solution in Chrome

Developing a front end in Chrome is fun because the browser provides so many debugging tools. One I often use is breakpoint debugging.

Chrome provides a DOM monitoring feature that automatically pauses when the DOM changes, so you can quickly locate who changed the height of the

On the Elements page, select the specified DOM node and click the first “…” Symbol (or use the right click), in the pop-up menu to choose “Break On”, you can select multiple.

  • Subtree Modifications: When a node tree changes
  • Attribute Modifications: When a node property changes
  • Node Removal: when a Node is removed (including child nodes)

When either is enabled, Chrome automatically interrupts the currently executing script code when a specific event occurs.

Because JavaScript Modifications to styles are nothing more than adding/removing classes or modifying the style property, you can use Attribute Modifications to find out which script is modifying the DOM.

The new problem

When doing front-end development, you often want to listen for changes to DOM nodes. When the DOM changes, a series of events are triggered.

In general, using polling to solve this problem is very simple, using setInterval to constantly check to see if the DOM has changed. This approach is simple and crude, but there are two problems: the time interval is set too long and DOM changes are not responsive enough; If the time interval is set too short, not only the CPU is wasted, but also the lag may occur.

You can also use requestAnimationFrame to do this, which is the same as setInterval, except that to some extent you can get real-time responses to DOM changes, but still waste CPU time slices.

Is there a better way?

In older versions of the DOM Events standard, there was a Mutation Events that listened for CHANGES in the DOM and triggered Events when the DOM changed.

Nine Mutation events are defined in DOM3: DOMAttrModified, DOMAttributeNameChanged, DOMCharacterDataModified, DOMElementNameChanged, DOMNodeInserted, DOMNodeInsertedIn ToDocument, DOMNodeRemoved, DOMNodeRemovedFromDocument, DOMSubtreeModified.

These nine events can be added directly to a DOM element via element.addeventListener.

However, Mutation events have been deprecated! And removed from the Web Standards event!

Due to performance issues, Mutation events can degrade the performance of DOM modifications by a factor of 1.5 to 7 and cannot be recovered by removing events.

And the implementation of this event varies from browser to browser.

So, starting with DOM4, Mutation Observers are recommended instead of Mutation events.

Mutation Observers

The Mutation Observer API can be used to monitor DOM changes, including attribute changes, node additions and deletions, content changes, and so on.

Where is higher than Mutation Events?

Why is Mutation Observers better than Mutation Events?

Since Mutation Events are Events that are generated when a DOM change is detected, they are triggered immediately when any DOM changes. Also, because events are synchronized, if the DOM changes a lot, a lot of event callbacks can occur, leading to serious performance problems.

Mutation Observers, though similar to Mutation Events, are not Events, and are asynchronously triggered, not with every DOM change, but once, waiting for multiple DOM changes to complete. Use an array to record the steps of DOM changes. This way, even with frequent DOM operations, the impact on performance is less noticeable.

For example, I now need to display a 1000-paragraph article on the page, which means I need to insert 1000

into the page.

Using Mutation Events, 1000 DOMNodeInserted Events are generated at this point; This is not the case with Mutation Observers, which fires once, yielding an array of 1,000 inserted nodes.

How do you use it?

MutationObserver is a constructor that uses new to create an instance of MutationObserver. This constructor accepts, as a parameter, a callback function that is called every time Mutation Observers are triggered. The function accepts two parameters, the first is an array of MutationRecord, which stores a record of changes to the DOM, The second parameter is the MutationObserver instance itself.

An instance of MutationObserver has three member methods: Observe, Disconnect, and takeRecords.

Observe Registers a listener. It accepts two parameters: the node to listen on and the configuration to listen on.

The listener configuration is an object that can have childList, Attributes, characterData, Subtree, attributeOldValue, characterDataOldValue, attributeFilter, To listen for any changes, you only need to set the corresponding property to true, and at least one of childList, Attributes, and characterData must appear.

attribute The data type describe
childList boolean Observe the target to add or remove child nodes
attributes boolean An attribute is added, deleted, or modified by the observed target
characterData boolean (target forcharacterDataNode, including text node, comment node, processing instruction node, etc.) the text content has changed
subtree boolean Not only to monitorovserveThe first parameter specifies the target to watch, and monitors all child nodes at the same time
attributeOldValue boolean In the monitorattributes, whether the content before the change should be recorded after the change of the attribute
characterDataOldValue boolean In the monitorcharacterDataIs it necessary to record the content before the change after the change of the text content
attributeFilter Array<string> An array of property names that can be used for filteringattributesThe change of the

After registration, the callback provided in the constructor is called, and the first argument gets the array of changes. The structure of the change object contains the following properties:

attribute The data type describe
type String Change type corresponding to the listening configuration objectchildList,attributes,characterData
target Node Change the target node iftypeattributescharacterData,targetIs the change node; otherwise, is the parent node of the change node
addedNodes NodeList List of nodes to be added (may benull)
removedNodes NodeList List of nodes to be deleted (possiblenull)
previousSibling Node The previous sibling of the node to be added or removed (may benull)
nextSibling Node The next sibling of the node to be added or removed (may benull)
attributeName String The name of the property that changed (possiblenull)
attributeNamespace String The attribute of the changeXML namespace(may benull)
oldValue String iftypeattributescharacterData,oldValueIs the value before the change, otherwise isnull

Disconnect is used to stop listening.

TakeRecords is used to empty and return the DOM change steps recorded in the current MutationObserver.

Browser compatibility

As you can see, compatibility is still very good, can be trusted to use.

conclusion

MutationObserver provides a more efficient and flexible DOM monitoring scheme than Mutation Events. You can customize your monitoring objects according to your needs, which can be of greater value in componentized projects — you can receive notification of changes in component content without the need to provide an interface inside the component.

However, the MutationObserver is good, don’t abuse it!

The Chrome Break On feature looks like a stripped-down version of MutationObserver and is very useful.


Pay attention to wechat public number: KnownsecFED, code to get more quality dry goods!