DOM 요소를 취득할 수 있는 다양한 방법이 있다. 하나의 요소를 다양한 방법으로 취득할 수 있는데 그 중에서 어떤 방법을 쓰는 것이 가장 좋은지, 상황에 맞는 방법은 무엇인지, 각 방법에 어떤 장단점이 있는지 궁금해서 조사를 해보았다.
getElement계열은 id
, class
, tag
등을 이용하여 요소를 가져올 수 있다. -s
가 붙은 메서드들은 여러 개의 요소를 동시에 가져온다.
Document.prototype.getElementById
메서드는 인수로 전달한 id 어트리뷰트 값을 갖는 요소를 탐색하여 반환한다. element 뒤에 -s
가 붙지 않았기 때문에 하나의 요소만 반환한다. 일반적으로 id는 중복이 불가능한 고유의 값이지만 HTML의 id 어트리뷰트는 중복이 가능한 값이다.
개발자가 id를 중복해서 쓰는 것도 하나의 방법이지만 개발자는 항상 실수를 할 수 있기 때문에 Document.prototype.getElementById
는 개발자의 의도와 다르게 동작할 수도 있다. 중복된 id 어트리뷰트 값이 있다면 가장 처음에 있는 값을 가져온다.
<ul>
<li id="banana">banana</li>
<li id="apple">apple</li>
<li id="orange">orange</li>
</ul>
<script>
const $apple = document.getElementById('apple');
</script>
document.prototype/element.prototype.getElementsByClassName
메서드는 인수로 전달한 class 어트리뷰트 값을 갖는 요소 노드들을 탐색하여 반환한다. -s
가 붙어있기 때문에 모든 노도 요소를 한꺼번에 반환한다. 이때 요소 노드들은 HTMLCollection 객체에 담아 반환한다.
<ul class="fruits">
<li class="banana">banana</li>
<li class="apple">apple</li>
<li class="orange">orange</li>
</ul>
<script>
const $fruits = document.getElementByClassName('fruits');
</script>
document.prototype/element.prototype.getElementsByTagName
메서드는 인수로 전달한 태그 이름을 갖는 요소 노드를 탐색하여 반환한다. -s
가 붙어있기 때문에 모든 노도 요소를 한꺼번에 반환한다. 이때 요소 노드들은 HTMLCollection 객체에 담아 반환한다.
getElementsByClassName
과 getElementsByTagName
메서드는 document 뿐 아니라 요소 뒤에 체이닝하여 사용할 수 있다.
<ul class="fruits">
<li class="banana">banana</li>
<li class="apple">apple</li>
<li class="orange">orange</li>
</ul>
<script>
const $elems = document.getElementByTagName('li');
[...$elems].forEach(elem => { elem.style.color = 'blue'; })
</script>
querySelector
과 querySelectorAll
메서드는 CSS 선택자를 이용하여 DOM 요소를 취득한다. CSS 선택자를 사용하기 때문에 클래스를 가져올 때 클래스 선택자인 .
을 빠트리지 않도록 주의가 필요하다.
document.prototype/element.prototype.querySelector
메서드는 인수로 전달한 CSS 선택자를 만족시키는 하나의 요소를 탐색하여 반환한다.
null
을 반환한다.getElementsByClassName
이나 getElementsByTagName
과 같이 요소 노드에 체이닝하여 사용할 수 있다.
<ul class="fruits">
<li class="banana">banana</li>
<li class="apple">apple</li>
<li class="orange">orange</li>
</ul>
<script>
const $fruits = document.querySelector('.fruits');
const $banana = $fruits.querySelector('.banana');
</script>
document.prototype/element.prototype.querySelectorAll
메서드는 인수로 전달한 CSS 선택자를 만족시키는 모든 요소 노드를 탐색하여 반환한다. 요소 노드는 DOM 컬렉션 객체인 NodeList에 담겨서 반환된다.
<ul class="fruits">
<li class="banana">banana</li>
<li class="apple">apple</li>
<li class="orange">orange</li>
</ul>
<script>
const $fruits = document.querySelectorAll('li');
</script>
getElementById
querySelector
querySelectorAll
getElementsByTagName
혹은 getElementsByClassName
이 반환하는 HTMLCollection 객체는 실시간으로 노드 객체의 상태 변경을 반영하는 live 객체로 동작하기 때문에 주의가 필요하다. 따라서 NodeList를 반환하는 querySelectorAll
을 사용하는 것이 더 적절하다. HTMLCollection이나 NodeList를 사용한다면 이를 배열로 변경하는 것이 개발자가 실수할 확률을 줄여준다. 두 객체 모두 유사 배열 객체이면서 이터러블이다. 두 객체 모두 배열로 변경이 가능하다.