I am in need of a way to detect if any DOM Node/Element has been removed or modified and instantly restore that element to the state in which it was before.
I tried to "backup" the body node and set the body.innerHTML to its original state every time MutationObserver is fired after the first run but that crashes the browser.
Is there any fast way to restore elements that have been modified or removed?
I am in need of a way to detect if any DOM Node/Element has been removed or modified and instantly restore that element to the state in which it was before.
I tried to "backup" the body node and set the body.innerHTML to its original state every time MutationObserver is fired after the first run but that crashes the browser.
Is there any fast way to restore elements that have been modified or removed?
Share asked Oct 16, 2015 at 7:19 SpoonGuySpoonGuy 752 silver badges4 bronze badges 3- 1 You can't restore a DOM element if you removed it. The only thing you can do is store it in a variable and later retrieve the DOM element from the variable. But once it's deleted, it's gone. – Joshua Bakker Commented Oct 16, 2015 at 7:30
- wouldn't it be easier to keep them from being removed? – dandavis Commented Oct 16, 2015 at 7:30
- 1 Well, how would I prevent them being removed or modified? The reason why I need this is to prevent modifications through the Dev-Tools of a browser. – SpoonGuy Commented Oct 16, 2015 at 8:16
2 Answers
Reset to default 3This is all I can e with (a bit hacky, but it works). Click test
or test #2
for removing nodes: http://codepen.io/zvona/pen/BowXaN?editors=001
HTML:
<div class='preserve'>
<h1>There can be anything inside this</h1>
<p>Some content</p>
</div>
<div class='preserve'>
<p>Some more content</p>
</div>
JS:
var preserved = document.querySelectorAll('.preserve');
var config = { attributes: true, childList: true, characterData: true };
var createFragment = function(elem, i) {
var frag = document.createElement('div');
var id = 'id-'+ new Date().getTime() +'-'+ i;
frag.setAttribute('id', id);
elem.parentNode.insertBefore(frag, elem);
elem.dataset.frag = id;
observer.observe(elem.parentNode, config);
}
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (!mutation.addedNodes.length && mutation.removedNodes.length) {
Array.prototype.forEach.call(mutation.removedNodes, function(elem) {
var frag = document.querySelector('#'+ elem.dataset.frag);
frag.parentNode.replaceChild(elem, frag);
createFragment(elem, frag.id.split('-')[2]);
});
}
});
});
Array.prototype.forEach.call(preserved, function(preserve, i) {
createFragment(preserve, i);
});
If you want to preserve all the nodes (aka document.querySelectorAll('*');
), then I think it bees very heavy from performance point of view.
The problem is to record the removed nodes.
In my case, I generate a xpath for every nodes in the document. When childList
triggered, generate again.
So that I can know the removed node's xpath, and can use the xpath to restore the node.
mutation.removedNodes.map((node) => {
const xpath = node.xpath // which is generated each time `childList` triggered
})
Hope to help you.