text: (window.webpackJsonp=window.webpackJsonp||[]).push([[19],{571:function(e,t,r){"use strict";r.r(t);var a=r(13),n=Object(a.a)({},(function(){var e=this,t=e.$createElement,r=e._self._c||t;return r("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[r("h2",{attrs:{id:"mutationobserver"}},[r("a",{staticClass:"header-anchor",attrs:{href:"#mutationobserver"}},[e._v("#")]),e._v(" MutationObserver")]),e._v(" "),r("p",[e._v("MutationObserver接口提供了监视对DOM树所做更改的能力。用于替代 "),r("a",{attrs:{href:"https://www.w3.org/TR/DOM-Level-3-Events/",target:"_blank",rel:"noopener noreferrer"}},[e._v("DOM3"),r("OutboundLink")],1),e._v(" 中的"),r("code",[e._v("Mutation event")]),e._v("。")]),e._v(" "),r("p",[r("code",[e._v("Mutation event")]),e._v("是"),r("span",{staticStyle:{color:"red"}},[e._v("同步执行")]),e._v("的，每次调用都需要从事件队列中取出事件，执行，然后事件队列中移除，期间需要移动队列元素。如果事件触发的较为频繁的话，每一次都需要执行上面的这些步骤。")]),e._v(" "),r("p",[e._v("且Mutation Events本身是事件且可以冒泡，所以捕获是采用的是事件冒泡的形式，如果冒泡捕获期间又触发了其他的MutationEvents的话，很有可能就会导致阻塞Javascript线程，甚至导致浏览器崩溃。")]),e._v(" "),r("p",[e._v("Mutation event用法如下:")]),e._v(" "),r("div",{staticClass:"language- line-numbers-mode"},[r("pre",{pre:!0,attrs:{class:"language-text"}},[r("code",[e._v("document.getElementById('list').addEventListener(\"DOMSubtreeModified\", function(){\n  console.log('列表中子元素被修改');\n}, false);\n")])]),e._v(" "),r("div",{staticClass:"line-numbers-wrapper"},[r("span",{staticClass:"line-number"},[e._v("1")]),r("br"),r("span",{staticClass:"line-number"},[e._v("2")]),r("br"),r("span",{staticClass:"line-number"},[e._v("3")]),r("br")])]),r("p",[e._v("Mutation Observer 是在DOM4中定义的，用于替代 mutation events 的新API，它的不同于events的是，所有监听操作以及相应处理都是在其他脚本执行完成之后异步执行的，并且是所有变动触发之后，将变动记录在数组中，统一进行回调的，也就是说，当你使用observer监听多个DOM变化时，并且这若干个DOM发生了变化，那么observer会将变化记录到变化数组中，等待一起都结束了，然后一次性的从变化数组中执行其对应的回调函数。")]),e._v(" "),r("p",[r("strong",[e._v("构造函数MutationObserver.MutationObserver()")])]),e._v(" "),r("p",[e._v("DOM 规范中的 "),r("code",[e._v("MutationObserver()")]),e._v(" 构造函数 —— 创建并返回一个新的观察器，他会在触发指定DOM事件时，调用指定的回调函数。")]),e._v(" "),r("div",{staticClass:"language- line-numbers-mode"},[r("pre",{pre:!0,attrs:{class:"language-text"}},[r("code",[e._v("var observer = new MutationObserver(callback);\n")])]),e._v(" "),r("div",{staticClass:"line-numbers-wrapper"},[r("span",{staticClass:"line-number"},[e._v("1")]),r("br")])]),r("p",[e._v("参数：一个回调函数，每当被指定的节点或子树以及配置项有Dom变动时会被调用。回调函数拥有两个参数：一个是描述所有被触发改动的 "),r("a",{attrs:{href:"https://developer.mozilla.org/zh-CN/docs/Web/API/MutationRecord",target:"_blank",rel:"noopener noreferrer"}},[e._v("MutationRecord"),r("OutboundLink")],1),e._v(" 对象数组，另一个是调用该函数的MutationObserver 对象。")]),e._v(" "),r("p",[e._v("返回值：一个新的、包含监听 DOM 变化回调函数的 MutationObserver 对象。")]),e._v(" "),r("p",[r("strong",[e._v("MutationObserver.observe()")])]),e._v(" "),r("p",[e._v("MutationObserver 的 observe() 方法提供了在观察者对象上注册需要观察的DOM节点，以及相应的配置项的方法。")]),e._v(" "),r("div",{staticClass:"language- line-numbers-mode"},[r("pre",{pre:!0,attrs:{class:"language-text"}},[r("code",[e._v("mutationObserver.observe(target[, options])\n")])]),e._v(" "),r("div",{staticClass:"line-numbers-wrapper"},[r("span",{staticClass:"line-number"},[e._v("1")]),r("br")])]),r("p",[e._v("参数：")]),e._v(" "),r("ul",[r("li",[e._v("target：DOM树中一个要观察变化的DOM "),r("a",{attrs:{href:"https://developer.mozilla.org/zh-CN/docs/Web/API/Node",target:"_blank",rel:"noopener noreferrer"}},[e._v("node"),r("OutboundLink")],1),e._v("，或者是被观察的子节点树的根节点。")]),e._v(" "),r("li",[e._v("options(可选)：一个可选的"),r("code",[e._v("MutationObserverInit")]),e._v(" 对象，此对象的配置项描述了DOM的哪些变化应该提供给当前观察者的callback。")])]),e._v(" "),r("p",[e._v("返回值：undefined")]),e._v(" "),r("p",[r("strong",[e._v("MutationObserverInit")])]),e._v(" "),r("p",[e._v("MutationObserverInit 字典描述了 MutationObserver 的配置。因此，它主要被用作 MutationObserver.observe() 方法的参数类型。")]),e._v(" "),r("blockquote",[r("p",[e._v("childLIst 设为 true 以监视目标节点目标节点的子节点的新增和删除（如果 subtree 为 true，则包含子孙节点）。默认值为false")]),e._v(" "),r("p",[e._v("subtree 设为 true 以将监视范围扩展至目标节点整个节点树中的所有节点。MutationObserverInit 的其他值也会作用于此子树下的所有节点，而不仅仅只作用于目标节点。默认值为 false。")]),e._v(" "),r("p",[e._v("attributes 设为 true 以观察受监视元素的属性值变更（新增/删除某个属性，或某个属性值发生变化）。默认值为 false。")]),e._v(" "),r("p",[e._v("characterData 如果目标节点为characterData节点(一种抽象接口,具体可以为文本节点,注释节点,以及处理指令节点)时。设为 true 以监视指定目标节点或子节点树中节点所包含的字符数据的变化。")]),e._v(" "),r("p",[e._v("attributeOldValue 在attributes属性已经设为true的前提下, 将发生变化的属性节点之前的属性值记录下来(记录到下面MutationRecord对象的oldValue属性中)，无默认值。")]),e._v(" "),r("p",[e._v("characterDataOldValue 在characterData属性已经设为true的前提下,将发生变化characterData节点之前的文本内容记录下来(记录到下面MutationRecord对象的oldValue属性中)，无默认值。")]),e._v(" "),r("p",[e._v("attributeFilter 一个属性名数组(不需要指定命名空间),只有该数组中包含的属性名发生变化时才会被观察到,其他名称的属性发生变化后会被忽略想要设置那些删选参数的话，就将其值设定为true。无默认值。")])]),e._v(" "),r("p",[r("strong",[e._v("MutationRecord")])]),e._v(" "),r("p",[e._v("每个 MutationRecord 都代表一个独立的 DOM 变化，在每次随 DOM 变化调用 MutationObserver 的回调函数时，一个相应的 MutationRecord 会被作为参数，传递给回调函数。")]),e._v(" "),r("p",[e._v("属性：")]),e._v(" "),r("blockquote",[r("p",[e._v('type 如果是属性变化，则返回 "attributes"；如果是 characterData 节点变化，则返回 "characterData"；如果是子节点树 childList 变化，则返回 "childList"')]),e._v(" "),r("p",[e._v("target 根据 MutationRecord.type，返回变化所影响的节点。\n对于属性 attributes 变化，返回属性变化的节点。\n对于 characterData 变化，返回 characterData 节点。\n对于子节点树 childList 变化，返回子节点变化的节点。")]),e._v(" "),r("p",[e._v("addedNodes 返回被添加的节点。\n如果没有节点被添加，则该属性将是一个空的 NodeList。")]),e._v(" "),r("p",[e._v("removedNodes 返回被移除的节点。\n如果没有节点被移除，则该属性将是一个空的 NodeList。\npreviousSibling 返回被添加或移除的节点之前的兄弟节点，或者 null。")]),e._v(" "),r("p",[e._v("nextSibling 返回被添加或移除的节点之后的兄弟节点，或者 null。")]),e._v(" "),r("p",[e._v("attributeName 返回被修改的属性的属性名，或者 null。")]),e._v(" "),r("p",[e._v("attributeNamespace 返回被修改属性的命名空间，或者 null。")]),e._v(" "),r("p",[e._v("oldValue 返回值取决于 MutationRecord.type。\n对于属性 attributes 变化，返回变化之前的属性值。\n对于 characterData 变化，返回变化之前的数据。\n对于子节点树 childList 变化，返回 null。")])]),e._v(" "),r("p",[r("strong",[e._v("MutationObserver.disconnect()")])]),e._v(" "),r("p",[e._v("MutationObserver 的 disconnect() 方法告诉观察者停止观察变动，且清空所有的MutationRecord对象。 可以通过调用其observe()方法来重用观察者。")]),e._v(" "),r("p",[e._v("如果被观察的元素被从DOM中移除，然后被浏览器的垃圾回收机制释放，此MutationObserver将同样被删除。")]),e._v(" "),r("div",{staticClass:"language- line-numbers-mode"},[r("pre",{pre:!0,attrs:{class:"language-text"}},[r("code",[e._v("mutationObserver.disconnect()\n")])]),e._v(" "),r("div",{staticClass:"line-numbers-wrapper"},[r("span",{staticClass:"line-number"},[e._v("1")]),r("br")])]),r("p",[e._v("参数：无")]),e._v(" "),r("p",[e._v("返回值：undefined")]),e._v(" "),r("p",[r("strong",[e._v("MutationObserver.takeRecords()")])]),e._v(" "),r("p",[e._v("MutationObserver 的 takeRecords() 方法返回已检测到但尚未由观察者的回调函数处理的所有匹配DOM更改的列表，使变更队列保持为空（从MutationObserver的通知队列中删除所有待处理的通知，并将它们返回到MutationRecord对象的新Array中）。此方法最常见的使用场景是在断开观察者之前立即获取所有未处理的更改记录，以便在停止观察者时可以处理任何未处理的更改。")]),e._v(" "),r("div",{staticClass:"language- line-numbers-mode"},[r("pre",{pre:!0,attrs:{class:"language-text"}},[r("code",[e._v("mutationRecords = mutationObserver.takeRecords()\n")])]),e._v(" "),r("div",{staticClass:"line-numbers-wrapper"},[r("span",{staticClass:"line-number"},[e._v("1")]),r("br")])]),r("p",[e._v("参数：无")]),e._v(" "),r("p",[e._v("返回值：返回一个MutationRecord 对象列表，每个对象都描述了应用于DOM树某部分的一次改动。")]),e._v(" "),r("p",[r("strong",[e._v("参考链接：")])]),e._v(" "),r("p",[r("a",{attrs:{href:"https://blog.csdn.net/weixin_45412353/article/details/107176246",target:"_blank",rel:"noopener noreferrer"}},[e._v("MutationObserver 用法总结( 监听节点、DOM变化 )"),r("OutboundLink")],1)]),e._v(" "),r("p",[r("a",{attrs:{href:"https://segmentfault.com/a/1190000040362863",target:"_blank",rel:"noopener noreferrer"}},[e._v("Mutation events和MutationObserver 监听DOM变化"),r("OutboundLink")],1)])])}),[],!1,null,null,null);t.default=n.exports}}]);