阅读 797

前端水印防删

前言

上篇文章说到了前端添加的水印可以很简单的通过浏览器控制台来删除或者隐藏,而对于之前的水印添加方式,只需要把dom上对应的类名删掉,那么这个dom上附带的水印就会被删除。所以要实现的就是防止设置的类名被删除掉。这里可以使用Web API接口MutationObserver来实现

MutationObserver接口,接口提供了监视对DOM树所做更改的能力。比如属性的增减或修改,子元素的增减。

方法作用
observe()配置MutationObserver在DOM更改匹配给定选项时,通过其回调函数开始接收通知。
disconnect()阻止 MutationObserver 实例继续接收的通知,直到再次调用其observe()方法,该观察者对象包含的回调函数都不会再被调用。
takeRecords()从MutationObserver的通知队列中删除所有待处理的通知,并将它们返回到MutationRecord对象的新Array中。

实现

构思: 获取到所有添加了水印类名的dom,然后监听dom属性的改变,当属性改变时,获取一下dom的classList,判断水印的class是否还存在。如果被删除,就重新添加进去

// 公共方法提取
function addObserve(mutation, container) {
  mutation.observe(container, {
    // 这里只需要监听属性
    attributes: true,
  })
}

/**
 * 防止删除类名
 * @param {String} className 类名
 */
function addListioner(className) {
  const MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
  const containerList = document.querySelectorAll(`.${className}`);
  if (MutationObserver) {
    // PS domTreeList是不可以直接遍历的
    [...containerList].forEach(container => {
      let mo = new MutationObserver(function () {
        // 防止删除水印类名
        const classList = container.classList;
        if (![classList].includes(className)) {
          // 如果classList中不存在水印的类名,就重新add进去
          container.classList.add(className);
          // 防止重复触发
          mo.disconnect();
          // 重新开始观察
          addObserve(mo, container);
        }
      });
      addObserve(mo, container);
    })
  }
}
复制代码

PS: 因为在监听器中又对dom的classList进行了操作,所以此次操作会重新触发监听器。所以在监听器触发后,需要先阻止观察,然后再重新开始观察。

文章分类
前端
文章标签