MutationObserver DOM
MutationObserver
let observer = new MutationObserver(callback);
DOM
observer.observe(node, config);
config
childListnodesubtreenodeattributesnodeattributeattributeFiltercharacterDatanode.data
attributeOldValuetrueattributescharacterDataOldValuetruenode.datacharacterData
type"attributes""characterData""childList"/
target"attributes""characterData""childList"addedNodes/removedNodes/previousSibling/nextSibling//attributeName/attributeNamespace/ XMLoldValueattributeOldValue/characterDataOldValue
<div> contentEditable
<div contentEditable id="elem">Click and <b>edit</b>, please</div>
<script>
let observer = new MutationObserver(mutationRecords => {
console.log(mutationRecords); // console.log(the changes)
});
//
observer.observe(elem, {
childList: true, //
subtree: true, //
characterDataOldValue: true //
});
</script>
<div> <b>edit</b> console.log
mutationRecords = [{
type: "characterData",
oldValue: "edit",
target: <text node>,
//
}];
<b>edit</b>
mutationRecords = [{
type: "childList",
target: <div#elem>,
removedNodes: [<b>],
nextSibling: <text node>,
previousSibling: <text node>
//
}, {
type: "characterData"
target: <text node>
// ...
// "edit " ", please"
//
}];
MutationObserver DOM
<div class="ads">Unwanted ads</div>
MutationObserver DOM
MutationObserver
MutationObserver
HTML markup
...
<pre class="language-javascript"><code>
//
let hello = "world";
</code></pre>
...
JavaScript Prism.js Prism Prism.highlightElem(pre) pre tag
DOMContentLoaded DOM pre[class*="language"] Prism.highlightElem
//
document.querySelectorAll('pre[class*="language"]').forEach(Prism.highlightElem);
HTML
let article = /* */
articleElem.innerHTML = article;
article HTML Prism.highlightElem
Prism.highlightElem
let article = /* */
articleElem.innerHTML = article;
let snippets = articleElem.querySelectorAll('pre[class*="language-"]');
snippets.forEach(Prism.highlightElem);
MutationObserver
let observer = new MutationObserver(mutations => {
for(let mutation of mutations) {
//
for(let node of mutation.addedNodes) {
//
if (!(node instanceof HTMLElement)) continue;
//
if (node.matches('pre[class*="language-"]')) {
Prism.highlightElement(node);
}
//
for(let elem of node.querySelectorAll('pre[class*="language-"]')) {
Prism.highlightElement(elem);
}
}
}
});
let demoElem = document.getElementById('highlight-demo');
observer.observe(demoElem, {childList: true, subtree: true});
HTML innerHTML JavaScript
MutationObserver
id="highlight-demo"
innerHTML MutationObserver
let demoElem = document.getElementById('highlight-demo');
//
demoElem.innerHTML = `
<pre class="language-javascript"><code> let hello = "world!"; </code></pre>
<div></div>
<div>
<pre class="language-css"><code>.class { margin: 5px; } </code></pre>
</div>
`;
MutationObserver document HTML /
observer.disconnect()
observer.takeRecords()
//
// disconnect
let mutationRecords = observer.takeRecords();
//
observer.disconnect();
...
observer.takeRecords() observer.takeRecords()
DOM
DOM
MutationObserver DOM attribute/
MutationObserver config
<code><pre>10 plnkrJSBincodepen