上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
返回列表 发新帖

[油猴脚本开发指南]MutationObserver的使用

[复制链接]
  • TA的每日心情
    慵懒
    2024-10-28 07:07
  • 签到天数: 193 天

    [LV.7]常住居民III

    712

    主题

    5961

    回帖

    6760

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    6760

    荣誉开发者喜迎中秋油中2周年生态建设者

    发表于 2021-9-15 23:41:57 | 显示全部楼层 | 阅读模式

    tia# MutationObserver

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

    具体可以参考https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver

    那Mutation Events是什么呢?

    Mutation Events

    可以参考https://developer.mozilla.org/en-US/docs/Web/API/MutationEvent

    MutationEvents目前已经被弃用,不再推荐此功能。虽然一些浏览器可能仍然支持它,但它可能已经从相关的 Web 标准中删除,可能正在被删除,或者可能只是为了兼容性目的而保留。

    Adding DOM mutation listeners to a document profoundly degrades the performance of further DOM modifications to that document (making them 1.5 - 7 times slower!). Moreover, removing the listeners does not reverse the damage.

    添加Dom Muatation Listeners对document进行dom修改时会严重降低性能,大概导致缓慢1.5-7倍,并且,移除listener并不能逆转这种破坏!

    以下为所有Mutation Events的列表

    DOMAttrModified
    DOMAttributeNameChanged
    DOMCharacterDataModified
    DOMElementNameChanged
    DOMNodeInserted
    DOMNodeInsertedIntoDocument
    DOMNodeRemoved
    DOMNodeRemovedFromDocument
    DOMSubtreeModified

    通常使用进行注册Mutation Event(也就是之前我介绍的那种方式)

    element.addEventListener("DOMNodeInserted", function (event) {
      // ...
    }, false);

    转变

    所以这时候我们为了避免性能的减缓,就使用了MutationObserver,其使用方式也相对之前有所改变

    构造函数

    MutationObserver()
    创建并返回一个新的 MutationObserver 它会在指定的DOM发生变化时被调用。

    使用方法

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

    MutationObserver例子

    选自博客https://hacks.mozilla.org/2012/05/dom-mutationobserver-reacting-to-dom-changes-without-killing-browser-performance/

    const targetNode = document.getElementById('some-id');
    
    // 观察器的配置(需要观察什么变动)
    const config = { attributes: true, childList: true, subtree: true };
    
    // 当观察到变动时执行的回调函数
    const callback = function(mutationsList, observer) {
        // Use traditional 'for loops' for IE 11
        for(let mutation of mutationsList) {
            if (mutation.type === 'childList') {
                console.log('A child node has been added or removed.');
            }
            else if (mutation.type === 'attributes') {
                console.log('The ' + mutation.attributeName + ' attribute was modified.');
            }
        }
    };
    
    // 创建一个观察器实例并传入回调函数
    const observer = new MutationObserver(callback);
    
    // 以上述配置开始观察目标节点
    observer.observe(targetNode, config);
    
    // 之后,可停止观察
    observer.disconnect();

    补充

    我大概查阅了一下资料,认为MutationObserve是为了解决性能问题而产生的api,但是除了MutationEvents的性能问题,其目的主要为了监控Dom的插入、修改、以及删除。注意,这并不代表addeventlitener的废除!由于api目前接触时间较短,可能对其有一定的错误理解,欢迎补充!撒花~

    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
  • TA的每日心情
    开心
    昨天 13:37
  • 签到天数: 213 天

    [LV.7]常住居民III

    305

    主题

    4189

    回帖

    4056

    积分

    管理员

    积分
    4056

    管理员荣誉开发者油中2周年生态建设者喜迎中秋油中3周年挑战者 lv2

    发表于 2021-9-16 09:32:26 | 显示全部楼层
    ggnb!学习学习
    上不慕古,下不肖俗。为疏为懒,不敢为狂。为拙为愚,不敢为恶。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    昨天 18:01
  • 签到天数: 879 天

    [LV.10]以坛为家III

    30

    主题

    732

    回帖

    7356

    积分

    荣誉开发者

    精通各种语言的HelloWord!

    积分
    7356

    荣誉开发者油中2周年生态建设者油中3周年挑战者 lv2

    发表于 2021-9-16 10:25:04 | 显示全部楼层

    ggnb!学习学习
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2022-7-5 00:02
  • 签到天数: 124 天

    [LV.7]常住居民III

    5

    主题

    168

    回帖

    927

    积分

    版主

    积分
    927

    荣誉开发者油中2周年

    发表于 2021-9-16 12:25:10 | 显示全部楼层
    好,慢慢学
    回复

    使用道具 举报

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表