DOM 노드의 주요 프로퍼티는 무엇이 있는지 학습해보자.
nodeType 프로퍼티는 DOM 노드의 '타입’을 알아내고자 할 때 쓰이는 구식 프로퍼티이다.
각 노드 타입은 상숫값을 가진다.
<body>
<script>
let elem = document.body;
// 타입을 알아봅시다.
alert(elem.nodeType); // 1 => 요소 노드
// 첫 번째 자식 노드
alert(elem.firstChild.nodeType); // 3 => 텍스트 노드
// 문서 객체의 타입 확인
alert( document.nodeType ); // 9 => 문서 객체
</script>
</body>
모던 자바스크립트에선 노드의 타입을 instanceof나 클래스 기반의 테스트를 이용해 확인하는데, 가끔은 nodeType를 쓰는 게 간단할 때도 있다. 다만, nodeType은 타입 확인 하는 데만 쓸 수 있고 바꾸지는 못한다.
nodeName이나 tagName 프로퍼티를 사용하면 DOM 노드의 태그 이름을 알아낼 수 있다.
alert( document.body.nodeName ); // BODY
alert( document.body.tagName ); // BODY
<body><!-- 주석 -->
<script>
// 주석 노드를 대상으로 두 프로퍼티 비교
alert( document.body.firstChild.tagName ); // undefined (요소가 아님)
alert( document.body.firstChild.nodeName ); // #comment
// 문서 노드를 대상으로 두 프로퍼티 비교
alert( document.tagName ); // undefined (요소가 아님)
alert( document.nodeName ); // #document
</script>
</body>
<body>
<p>p 태그</p>
<div>div 태그</div>
<script>
console.log( document.body.innerHTML ); // 내용 읽기
document.body.innerHTML = '새로운 BODY!'; // 교체
console.log( document.body.innerHTML );
</script>
</body>
outerHTML 프로퍼티엔 요소 전체 HTML이 담겨있다. outerHTML은 innerHTML에 요소 자체를 더한 것이라고 생각하면 된다.
<div id="elem">Hello <b>World</b></div>
<script>
alert(elem.outerHTML); // <div id="elem">Hello <b>World</b></div>
</script>
innerHTML과 달리 outerHTML을 사용해서 HTML을 쓸땐 요소 자체가 바뀌지 않는다. 대신 outerHTML은 DOM 안의 요소를 교체한다.
<div>Hello, world!</div>
<script>
let div = document.querySelector('div');
// div.outerHTML를 사용해 <p>...</p>로 교체
div.outerHTML = '<p>새로운 요소</p>'; // (*)
// 어! div가 그대로네!
alert(div.outerHTML); // <div>Hello, world!</div> (**)
</script>
위와 같은 결과가 나타난 이유는 outerHTML에 하는 할당 연산이 DOM 요소(outerHTML 연산의 대상으로, 위 예시에선 변수 div)를 수정하지 않기 때문이다. 할당 연산은 요소를 DOM에서 제거하고 새로운 HTML 조각을 넣습니다.
즉, div.outerHTML=...는 아래와 같은 일을 한다.
A new element
을 삭제 후 생긴 공간에 삽입=> 새롭게 만들어진 요소를 참조하려면 DOM 쿼리 메서드를 사용해야 한다.
innerHTML 프로퍼티는 요소 노드에만 사용할 수 있다.
그래서 텍스트 노드 같은 다른 타입의 노드에는 innerHTML과 유사한 역할을 해주는 프로퍼티인 nodeValue와 data를 사용해야 한다.
(이 두 프로퍼티는 아주 유사하고, 실무에서도 구분 없이 쓰긴 하지만 명세서상에 작은 차이가 있긴 합니다만 data가 좀 더 짧기 때문에 여기선 data를 사용)
<body>
안녕하세요.
<!-- 주석 -->
<script>
let text = document.body.firstChild;
alert(text.data); // 안녕하세요.
let comment = text.nextSibling;
alert(comment.data); // 주석
</script>
</body>
텍스트 노드의 내용을 읽거나 수정하는 일은 일어날 법 한데 주석 노드는 왜 이런 기능이 필요할까?
개발자들은 종종 아래와 같은 방식으로 정보나 지시사항을 HTML에 삽입한다고 한다.
<!-- if isAdmin -->
<div>관라자로 로그인하였습니다!</div>
<!-- /if -->
이럴 때 data 프로퍼티 기능을 사용해 주석 노드의 내용을 읽고 삽입된 지시사항을 처리하면 유용하다.
<div id="news">
<h1>주요 뉴스!</h1>
<p>화성인이 지구를 침공하였습니다!</p>
</div>
<script>
// 주요 뉴스! 화성인이 지구를 침공하였습니다!
alert(news.textContent);
</script>
그런데 굳이 텍스트 읽기를 왜 할까?
=> textContent를 사용하면 텍스트를 '안전한 방법’으로 쓸 수 있기 때문에 실무에선 textContent를 쓰기 용으로 유용하게 사용한다.
사용자가 입력한 임의의 문자열을 다시 출력해주는 경우를 생각해 보자.
<div id="elem1"></div>
<div id="elem2"></div>
<script>
let name = prompt("이름을 알려주세요.", "<b>이보라</b>");
elem1.innerHTML = name;
elem2.textContent = name;
</script>
개발을 하다보면 사용자의 입력값을 받아 처리해야 하는 경우가 많다. 이때 사용자가 입력한 값은 텍스트로 처리되어야 하기때문에, 예상치 못한 HTML이 사이트에 침투하는 것을 막으려면 textContent를 사용해야 한다.
hidden 속성과 hidden 프로퍼티는 요소를 보여줄지 말지 지정할 때 사용할 수 있다.
hidden은 HTML 안에서 쓸 수도 있고 자바스크립트에서도 쓸 수 있다.
<div>아래 두 div를 숨겨보자.</div>
<div hidden>HTML의 hidden 속성 사용하기</div>
<div id="elem">자바스크립트의 hidden 프로퍼티 사용하기</div>
<script>
elem.hidden = true;
</script>
hidden은 기술적으로 style="display:none"와 동일하다. 짧다는 점만 다름ㅎ
<div id="elem">깜빡이는 요소</div>
<script>
setInterval(() => elem.hidden = !elem.hidden, 1000);
</script>
nodeType - 요소 타입을 알고 싶을 때 사용
nodeName/tagName - 요소 노드의 태그 이름을 알아낼 때 사용 (읽기 전용)
innerHTML - 요소 안의 HTML을 읽고, 수정도 가능
outerHTML - 요소의 전체 HTML을 알아낼 수 있다.
nodeValue/data - 요소가 아닌 노드(텍스트, 주석 노드 등)의 내용을 읽을 때 사용. 주로 data를 많이 사용하는 편이며 내용을 수정할 때도 이 프로퍼티를 쓸 수 있다.
textContent - HTML에서 모든 <태그>를 제외한 텍스트만 읽을 때 사용
hidden - true로 설정하면 CSS에서 display:none을 설정한 것과 동일하게 동작합니다.
참고자료