什么是MutationObserver

MutationObserver接口提供了监督对DOM树所做更改的能力。它被设计为旧的Mutation Events性能的替代品,该性能是DOM3 Events标准的一部分。

其实就是当指定的DOM发生变化时,咱们应用MutationObserver定义的办法会被执行。
如果你还没有get到点的话,不必急,上面介绍个实例。
有时候,当咱们的性能都是一些弹框类的款式,不会经常出现时,
比方账号登陆,手机登陆,重置明码,绑定手机号等等。

用户更加关注后续的业务,上述这些性能只是辅助性能,这个我的项目的首次版本中,我将所有的性能都写在了index.html中默认暗藏,大略的构造就是:

<div class = "loginPage"></div><div class = "phoneLoginPage"></div><div class = "resetpwdPage"></div><div class = "bindphonePage"></div>

而后在应用的时候显示进去。
这样写性能实现上没什么问题,也很好了解,
然而后续优化的时候发现,性能沉积到肯定水平,造成index.html十分的臃肿,代码外面对于图片的援用都会造成首次加载时,十分多的http申请。

自然而然我想到的解决方案 是将单个的性能都模块化,当须要时往页面中增加。我在index.html中增加一个容器,专门放下面这些性能。

<div class = "contont-div"></div>

而后每个性能一个js脚本,做成单例,当须要的时候show进去,不须要的时候hide

(function (g) {    g.SinglePage.loginPage = (function () {        var _$reg = null;        return {            show: function () {                if (_$reg) {                    return;                }                _$reg = ......                //上面是show的具体业务逻辑省略            },            hide: function () {                if (_$reg) {                    _$reg.remove();                }                _$reg = null;            }        }    })();}(window))

最开始的时候,所有都很顺利,当须要登录的时候,我关上登陆,而后在其余面板关上时候敞开登陆框,然而随着性能越来越多,呈现了一个问题,我不确定我关上的面板什么时候会被敞开了。

$('.contont-div').html();

因为用的是jq的html办法往容器中增加html代码,显示上不会有什么问题,然而,当我不晓得我关上的面板什么时候敞开时,我就没法让单例销毁,造成的结果就是不是我手动敞开的单例,再也打不开了,因为,单例的实例没有被销毁。

因而应用了MutationObserver。
为了防止咱们在监测到dom发生变化时,用switch case 去找对应的单例的实例,咱们革新一下性能的html

//登陆性能<div class = "mul_loginPage"></div>

其中mul_前面的字符串和登陆性能的脚本名称保持一致。
每个单例代码中都蕴含hide办法,用于革除实例。
其余性能同理。

 let targetNode = document.querySelector(`.contont-div`); let config = {     childList: true }; const mutationCallback = (mutations) => {     for (let mutation of mutations) {         let type = mutation.type;         switch (type) {             case "childList":                 let _removeNodes = mutation.removedNodes;                 for (let i = 0, l = _removeNodes.length; i < l; i++) {                     let _tmpNode = _removeNodes[i];                     let _class = $(_tmpNode).attr('class');                     if (!_class) {                         continue;                     }                     let _arg = _class.split('_');                     var _sj = _arg[1];                     if (_sj && g.SinglePage[_sj]) {                         g.SinglePage[_sj].hide();                     }                 }                 break;         }     } }; let observer = new MutationObserver(mutationCallback); if (targetNode) {     observer.observe(targetNode, config); }

这样,我就不必放心当其余单例笼罩已有单例时,被笼罩的单例不会革除实例的问题了。