MutationEvent는 DOM의 변화(요소 추가, 제거 등)를 감지하는 이벤트의 인터페이스이다. DOMNodeInserted, DOMNodeRemoved와 같은 이벤트가 여기에 속한다.
하지만 MutationEvent는 deprecated 되었다. (!)

MDN에서는 MutationEvent 대신 MutationObserver를 사용하는 것을 권장하고 있다.
MutationEvent를 사용하면 콘솔 창에 다음과 같은 경고 메시지가 나타난다. 
MutationEventMutationEvent를 일으킬 수 있고, 이는 JS 스레드를 막히게 하거나 브라우저 충돌을 초래한다.DOMAttrModifiedDOMAttributeNameChangedDOMCharacterDataModifiedDOMElementNameChangedDOMNodeInsertedDOMNodeInsertedIntoDocumentDOMNodeInserted 이벤트가 먼저 발생된다.DOMNodeRemovedDOMNodeRemovedFromDocumentDOMNodeRemoved 이벤트가 먼저 발생된다.DOMSubtreeModifiedelement.addEventListener('DOMNodeInserted', e => {
// ...
});
MutationObserver// mutationList: 일어난 변경 각각을 나타내는 MutationRecord 배열
// observer: 콜백을 호출한 MutationObserver 자체
const observer = new MutationObserver((mutationList, observer) => {
if (mutationList[0].addedNodes.length > 0) {
// ...
}
});
// DOM 노드 변경 알림 수신 설정
// element: 변경을 감지할 DOM 노드 또는 하위 트리 루트로서의 Node(Element 포함)
// options: 알림 수신 설정 옵션
observer.observe(element, { childList: true, subtree: true });
// 알림 큐를 비우고, 큐에서 대기 중인 알림(MutationRecord)으로 구성된 배열 반환
const mutations = observer.takeRecords();
if (mutations.length > 0) {
// ...
}
// DOM 노드 변경 알림 수신 해제 (observe()로 다시 수신 가능)
observer.disconnect();
MutationRecord: 노드에 일어난 변경을 나타내는 인터페이스
addedNodes: 새로 추가된 노드가 들어있는 배열(NodeList), 혹은 빈 배열attributeName: 바뀐 속성(attribute)의 이름을 나타내는 문자열 혹은 nullattributeNamespace: 바뀐 속성(attribute)의 네임스페이스를 나타내는 문자열 혹은 nullnextSibling: 추가됐거나 제거된 노드의 다음 형제 혹은 nulloldValuetype이 attributes라면 변경 전 속성 값type이 characterData라면 변경 전 노드의 텍스트 데이터type이 childList라면 nullpreviousSibling: 추가됐거나 제거된 노드의 이전 형제 혹은 nullremovedNodes: 제거된 노드가 들어있는 배열(NodeList), 혹은 빈 배열targettype이 attributes라면 속성이 변경된 노드type이 characterData라면 CharacterData 노드type이 childList라면 자식이 변경된 노드type: attributes(속성 변경), characterData(CharacterData 노드 변경), childList(노드 트리 변경)MutationObserverInit: observe()에 인자로 들어가는 options의 인터페이스
subtree
true일 경우 target이 루트인 하위 트리 전체를 주시falsechildList
true일 경우 대상 노드에 자식이 추가되거나 제거되는 것을 감지subtree가 true면 자손들의 자식 변경도 감지falseattributes
true일 경우 노드 또는 노드 속성 변경 감지false지만, attributeFilter나 attributeOldValue가 지정된 경우 truefalse로 설정한 경우 TypeError 발생attributeFilter
attributeOldValue
true일 경우 노드의 속성 변경을 감지했을 때 바뀌기 전의 값 기록falsecharacterData
true일 경우 대상 노드 내의 텍스트가 바뀌는 것을 감지subtree가 true면 자손들의 텍스트 변경도 감지false지만, characterDataOldValue가 지정된 경우 truecharacterDataOldValue가 true인 상태에서 true로 설정한 경우 TypeError 발생characterDataOldValue
true일 경우 노드의 텍스트 변경을 감지했을 때 바뀌기 전의 값 기록falseinterface MutationObserverInit {
/** Set to a list of attribute local names (without namespace) if not all attribute mutations need to be observed and attributes is true or omitted. */
attributeFilter?: string[];
/** Set to true if attributes is true or omitted and target's attribute value before the mutation needs to be recorded. */
attributeOldValue?: boolean;
/** Set to true if mutations to target's attributes are to be observed. Can be omitted if attributeOldValue or attributeFilter is specified. */
attributes?: boolean;
/** Set to true if mutations to target's data are to be observed. Can be omitted if characterDataOldValue is specified. */
characterData?: boolean;
/** Set to true if characterData is set to true or omitted and target's data before the mutation needs to be recorded. */
characterDataOldValue?: boolean;
/** Set to true if mutations to target's children are to be observed. */
childList?: boolean;
/** Set to true if mutations to not just target, but also target's descendants are to be observed. */
subtree?: boolean;
}
options의 경우, 적어도 childList, attributes, characterData 중 하나는 true여야 하며, 그렇지 않으면 TypeError가 발생한다.
MutationEvent에서 MutationObserver로 전환하기DOMNodeInsertedmutationList 배열의 요소 객체에는 새로 추가되는 DOM 요소를 저장하는 프로퍼티인 addedNodes 배열이 있다.addedNode 요소 개수가 1개 이상이면 새로운 요소가 추가되었다고 판단할 수 있다.const element = document.querySelector('#root') as HTMLDivElement;
// Before
element.addEventListener('DOMNodeInserted', e => {
// ...
});
// After
const observer = new MutationObserver((mutationList, observer) => {
if (mutationList[0].addedNodes.length > 0) {
// ...
}
});
observer.observe(element, { childList: true, subtree: true });DOMNodeRemovedmutationList 배열의 요소 객체에는 제거된 DOM 요소를 저장하는 프로퍼티인 removedNodes 배열이 있다.removedNodes 요소 개수가 1개 이상이면 제거된 요소가 존재한다고 판단할 수 있다.const element = document.querySelector('#root') as HTMLDivElement;
// Before
element.addEventListener('DOMNodeRemoved', e => {
// ...
});
// After
const observer = new MutationObserver((mutationList, observer) => {
if (mutationList[0].removedNodes.length > 0) {
// ...
}
});
observer.observe(element, { childList: true, subtree: true });MutationEvent - Web APIs | MDN
MutationObserver - Web API | MDN