티스토리 뷰

320x100

이 글은 주니어 개발자가 쓴 글로 오류가 있을 수 있습니다.

문제가 있거나 수정이 필요한 부분은 댓글로 알려주시면 감사하겠습니다.

 

Mozilla 기여자가 작성한 MDN에 대해 CC-BY-SA 2.5 라이선스에 따라 사용할 수 있습니다.


MutationObserver란?

DOM 변경을 관찰합니다. DOM3 이벤트 명세의 Mutation Events를 대체합니다.

구문

  • var observer = new MutationObserver(callback)
  • callback: DOM 변경 시 호출될 함수.
    • entries: 각 DOM의 변경을 나타내는 MutationRecord 형식의 오브젝트 배열.
    • observer: Observer 자기 자신. 특정 조건이 되면 관찰을 중단하는 등의 용도로 사용 가능.

메서드

  • disconnect(): 해당 observer의 모든 element target에 대한 관찰을 중단한다.
  • observer(target, options): 특정 element에 대한 관찰을 시작한다.
  • takeRecords(): 감지되었지만 아직 observer의 콜백 함수에 의해 처리되지 않은 entry가 들어있는 observer의 레코드 큐를 비우고 안에 든 MutationRecords 배열을 반환한다. 주로 diconnect 전에 남아있는 큐를 비워 처리하는 용도로 사용한다.

예시 코드

<!DOCTYPE html>
<html>
  <head>
    <title>MutationObserver Example</title>
  </head>

  <body>
    <div id="myDiv">
      <form id="myForm">
        <input id="myInput" />
      </form>
    </div>
    <button id="attributes">Change attributes</button>
    <button id="childList">Change childList</button>
    <button id="characterData">Change characterData</button>
    <button id="subtree">Change subtree</button>
    <script src="index.js"></script>
  </body>
</html>
const div = document.getElementById("myDiv");
const form = document.getElementById("myForm");
const input = document.getElementById("myInput");

document.getElementById("attributes").addEventListener("click", () => {
  div.setAttribute("class", "new"); // 대상에 변경 발생 - 속성 변경
});

document.getElementById("childList").addEventListener("click", () => {
  div.textContent = "Text Changed"; // 대상에 변경 발생 - 텍스트 노드 추가
});

document.getElementById("characterData").addEventListener("click", () => {
  // characterData: true, subtree: true 일 때만 관찰됨(관찰 대상이 div이기에 subtree도 true로 설정)
  div.childNodes[0].textContent = "characterData Changed"; // 자손에 변경 발생 - characterData 노드 값 변경
});

// 주의: childList 버튼을 누른 이후에는 input 요소가 사라져서 발생하지 않음
document.getElementById("subtree").addEventListener("click", () => {
  // attributes: true, subtree: true 일 때만 관찰됨
  // attributeFilter에 "type"이 없으면 관찰되지 않음
  input.type = "number"; // 자손에 변경 발생 - 속성 변경
});

// MutationObserver 생성
const observer = new MutationObserver((mutationRecords) => {
  mutationRecords.forEach((mutation) => console.log(mutation));
});

// 관찰 내용 설정
// childList, attributes, characterData 중 최소 한 가지는 true여야 하며
// subtree가 true일 때, 자손 노드에서 위 세 가지 설정 중 true인 것을 관찰한다.
const config = {
  childList: true, // 텍스트 노드를 포함한 하위 요소의 변경(추가/삭제)을 관찰
  attributes: true, // 속성 변경을 관찰
  characterData: true, // characterData 노드 값 변경 관찰
  subtree: true, // 자손 노드의 변경 관찰
  attributeOldValue: true, // 변경 전 속성 값을 저장
  characterDataOldValue: true, // 변경 전 데이터 값을 저장
  // attributeFilter: ["class"], // 관찰할 속성명 리스트
};

// 관찰 대상 등록
observer.observe(div, config);

// 관찰 중단
// 테스트 시, 주석 처리해야 관찰 가능
// observer.disconnect();

참고자료

MDN - MutationObserver

MDN - characterData

320x100
댓글