Front-end – How to listen for dom changes – prevent watermark from being deleted or changed
How do I listen for DOM changes?
Var observer = new MutationObserver(callback)
- Documents: developer.mozilla.org/zh-CN/docs/…
MutationObserver advantages
Optimize the efficiency of frequent DOM manipulation
- For example, if you insert 1000 paragraphs (P elements) in a row into the document, 1000 insert events will be fired continuously, executing the callback function for each event, which is likely to cause the browser to stall.
- The MutationObserver, on the other hand, fires only once after all 1000 paragraphs have been inserted.
Difference from events (conceptually, close to events)
- Event: Is triggered synchronously.
- When the DOM changes, the corresponding event is triggered immediately.
- MutationObserver: Is triggered asynchronously
- DOM changes are not triggered immediately, but wait until all current DOM operations are complete.
Example code:
<! DOCTYPEhtml>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="someElement">
<div>111</div>
<div>222</div>
<div>3333</div>
</div>
<script>
function handleClick (type) {
const targetNode = document.querySelector("#someElement");
if (type < 0) {
targetNode.removeChild(targetNode.lastElementChild)
} else {
targetNode.appendChild(document.createElement('br'))}}</script>
<div>
<button onclick="handleClick(1)">+ 1</button>
<button onclick="handleClick(-1)">- 1</button>
</div>
<script>
// MutationObserver partial code
const targetNode = document.querySelector("#someElement");
const callback = (obj) = > {
console.log(obj)
}
const observer = new MutationObserver(callback);
observer.observe(targetNode, {
childList: true.// Check whether the target child node is added or removed
attributes: true.// Observe attribute changes
subtree: true // Observe the descendant node, which defaults to false
})
</script>
</body>
</html>
Copy the code
Practical application: prevent watermark from being deleted or changed
Use MutationObserver to prevent the watermark from being removed or changed
// This method is to prevent the user from modifying the style through developer tools/or directly removing the watermark
const observer = new MutationObserver(() = > {
const wmInstance = document.querySelector('.watermark') // Get your watermark dom
if(! wmInstance) {console.log('Watermark is removed!! ')
document.body.appendChild(watermark)
return
}
if (wmInstance.getAttribute('style') !== styleStr) {
console.log('Changed the watermark style!! ')
wmInstance.setAttribute('style', styleStr)
}
})
observer.observe(document.body, {
childList: true.// Check whether the target child node is added or removed
attributes: true.// Observe attribute changes
subtree: true // Observe the descendant node, which defaults to false
})
Copy the code
Complete code :(generates canvas watermark image, using MutationObserver to prevent watermark from being deleted or changed)
<script>
function watermark (text1, text2) {
var canvas = document.createElement('canvas')
canvas.width = 150
canvas.height = 120
canvas.style.display = 'none'
var shuiyin = canvas.getContext('2d')
// Control the text rotation Angle and up and down position
shuiyin.rotate(-20 * Math.PI / 180)
shuiyin.translate(-50.20)
// Text color
shuiyin.fillStyle = '#dedede'
// Text style
shuiyin.font = '100 16px "PingFang SC", "Microsoft YaHei", Arial, sans-serif '
shuiyin.fillText(text1, canvas.width / 3, canvas.height / 2)
shuiyin.fillText(text2, canvas.width / 3, canvas.height / 2 + 20)
/* Create a new tag to fill the canvas watermark. The body */ is not added directly because z-index affects individual content
var watermark = document.createElement('div')
const styleStr = `
position:fixed;
top:0;
left:0;
width:100vw;
height:100vh;
z-index:99;
pointer-events:none;
background-repeat:repeat;
mix-blend-mode: multiply;
background-image:url('${canvas.toDataURL('image/png')}') `
watermark.setAttribute('style', styleStr)
watermark.classList.add('watermark')
document.body.appendChild(watermark)
// This method is to prevent the user from using the console to change the style to remove the watermark effect
/* MutationObserver is an interface that listens for changes in the DOM structure. * /
const observer = new MutationObserver((aa) = > {
// console.dir(aa)
const wmInstance = document.querySelector('.watermark')
if(! wmInstance) {console.log('Watermark is removed!! ')
document.body.appendChild(watermark)
return
}
if (wmInstance.getAttribute('style') !== styleStr) {
console.log('Changed the watermark style!! ')
wmInstance.setAttribute('style', styleStr)
}
})
observer.observe(document.body, {
childList: true.// Check whether the target child node is added or removed
attributes: true.// Observe attribute changes
subtree: true // Observe the descendant node, which defaults to false
})
}
watermark('qwer'.'are you qwer')
</script>
Copy the code
Code words are not easy