728x90
창이 열리면 input 태그에 focus를 주어야 하는데 자꾸 다른 곳에서 DOM이 변경되면서 focus가 나가버리는 상황이 있었다. 고민하다가 DOM이 변경될 때 input 태그에 focus를 주는 방법을 없을까? 하고 찾아보니 Mutation Observer가 있었다.

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MutationObserver</title>
<script>
function addRow() {
let list = document.querySelector('ul');
let lastRow = document.querySelector('li:last-child');
let newRowNum = parseInt(lastRow.textContent.replace(/[^0-9]/g, '')) + 1;
let row = document.createElement('li');
row.textContent = newRowNum + '번째 아이템';
list.appendChild(row);
}
</script>
</head>
<body>
<button onclick="addRow();">추가하기</button>
<ul>
<li>1번 아이템</li>
</ul>
</body>
</html>

다음과 같이 페이지에서 ul에 li가 추가되거나 텍스트의 내용이 변경되거나 속성이 변경되거나 하는 것들을 감지하고 싶다면 Mutation Observer를 사용하면 된다.
Mutation Observer를 이용하면 특정 노드의 DOM 변경을 감지할 수 있다. html 태그나 body 태그에 사용하여 페이지의 전체적인 변경을 감지할 수도 있을 것 같다.
위에 작성한 예제에 ul에 li가 추가될 경우 alert을 띄우고 싶다면 다음과 같이 Mutation Observer를 사용하면 된다.
// Mutation Observer
// 감시 대상 node 선택
let target = document.querySelector('ul');
// 감시자 인스턴스 만들기
let observer = new MutationObserver((mutations) => {
// 노드가 변경 됐을 때의 작업
alert('DOM 변경 감지');
})
// 감시자의 설정
let option = {
attributes: true,
childList: true,
characterData: true
};
// 대상 노드에 감시자 전달
observer.observe(target, option);

Mutation Observer를 사용할 때 Option으로 줄 수 있는 항목은 다음과 같다.
속성 | 설명 | 기본값 |
childList | 대상 노드의 자식 요소(텍스트 포함)의 변화 감지 | false |
attributes | 대상 노드의 속성 변화 감지 | false |
characterData | 대상 노드의 데이터 변화 감지 | false |
subtree | 대상 노드의 자식 요소뿐만 아니라 후손 요소의 변화까지 감지 | false |
attributeOldValue | 대상 노드의 속성 변경 전의 값도 기록에 남김 | false |
characterDataOldValue | 대상 노드의 데이터 변경 전의 값도 기록에 남김 | false |
attributeFilter | 모든 속성의 변화를 감지할 필요가 없는 경우 속성의 네임 스페이스 없이 속성 로컬 명의 배열로 설정 |
속성 중 최소한 childList, attributes, characterData는 true로 설정해야 한다.

아직 배울게 많은 것 같다. Mutation Observer 정리 끝.
· 참고
MDN - MutationObserver (https://developer.mozilla.org/ko/docs/Web/API/MutationObserver)
728x90
'Web > JS' 카테고리의 다른 글
[JS] 팝업창이 닫힐 때 특정 동작 수행하기 (0) | 2021.02.17 |
---|---|
[JS] jQuery Ajax callback 함수에서 전역 변수에 값 대입하기 (0) | 2021.02.16 |
[JS] Chrome Extension 제작 - 한국인 있나요? 유튜브 한글 댓글만 보기 (4) | 2020.12.23 |
[JS] Pseudo Element(가상 엘리먼트) style JavaScript로 변경하기 (0) | 2020.09.15 |
[JS] Chart.js 원형 차트, 사용자 지정 범례 그리기!(pie chart, custom legend) (2) | 2020.07.13 |