모던 자바스크립트 (문서) 18-4. getElement*, querySeletor*로 요소 검색하기
document.getElementById(id)
: 요소에 id 속성이 있는 경우 위치에 상관없이 해당 요소에 접근할 수 있게하는 메서드
<div id="elem">
<div id="elem-content">Element</div>
</div>
<script>
// 요소 얻기
let elem = document.getElementById('elem');
// 배경색 변경하기
elem.style.background = 'red';
</script>
<div id="elem">
<div id="elem-content">Element</div>
</div>
<script>
// 변수 elem은 id가 'elem'인 요소를 참조합니다.
elem.style.background = 'red';
// id가 elem-content인 요소는 중간에 하이픈(-)이 있기 때문에 변수 이름으로 쓸 수 없습니다.
// 이럴 땐 대괄호(`[...]`)를 사용해서 window['elem-content']로 접근하면 됩니다.
</script>
※ id를 따서 만들어진 전역변수를 요소 접근시에 사용하지 말것
: id에 대응하는 전역변수는 명세서의 내용을 구현해 만들어진 것으로 표준이긴 하지만 하위 호환성을 위한 동작임
: 브라우저는 스크립트의 네임스페이스와 DOM의 네임스페이스를 함꼐 사용할 수 있도록 해서 개발자의 편의를 도모
: 스크립트가 간단할 때는 괜츦으나, 이름이 충돌할 가능성이 생김
: 요소의 출처가 명확한 경우에 id를 사용해 요소에 직접 접근할 것을 권장
=> 실무에서는 document.getElementById를 사용할 것
요소.querySeletorAll(css)
: 요소의 자식 요소중 주어진 CSS 선택자에 대응하는 요소 모두를 반환
<ul>
<li>1-1</li>
<li>1-2</li>
</ul>
<ul>
<li>2-1</li>
<li>2-2</li>
</ul>
<script>
let elements = document.querySelectorAll('ul > li:last-child');
for (let elem of elements) {
alert(elem.innerHTML); // "1-2", "2-2"
}
</script>
※ querySeletorAll은 가상클래스에서도 사용 가능
: :hover, :active 같은 CSS 선택자의 가상 클래스 (pseudo-class)도 사용 가능
: document.querySelectorAll(':hover')를 사용하면
마우스 포인터가 위에 있는 요소 모두를 담은 컬렉션이 반환 됨
> 이때 컬렉션은 DOM 트리 최상단에 위치한 <html> 부터 가장 하단의 요소 순으로 채워짐
요소.querySelector(css)
: 주어진 css 선택자에 대응하는 요소 중 첫번째 요소를 반환
: 요소.querySelectorAll(css)[0]과 동일
요소.matches(css)
: 요소가 주어진 CSS 선택자와 일치하는지 여부를 boolean으로 반환
<a href="http://example.com/file.zip">...</a>
<a href="http://ya.ru">...</a>
<script>
// document.body.children가 아니더라도 컬렉션이라면 이 메서드를 적용할 수 있습니다.
for (let elem of document.body.children) {
if (elem.matches('a[href$="zip"]')) {
alert("주어진 CSS 선택자와 일치하는 요소: " + elem.href );
}
}
</script>
요소.closest(css)
: 요소 자기 자신을 포함하여 CSS 선택자와 일치하는 가장 가까운 조상 요소를 찾음
: 해당 요소부터 시작해 DOM 트리를 한 단계씩 거슬러 올라가면서 원하는 요소를 찾음
- 조상(ancestor) 요소
: 부모 요소의 부모 요소 등 DOM 트리 특정 요소의 상위에 있는 요소들
<h1>목차</h1>
<div class="contents">
<ul class="book">
<li class="chapter">1장</li>
<li class="chapter">2장</li>
</ul>
</div>
<script>
let chapter = document.querySelector('.chapter'); // LI
alert(chapter.closest('.book')); // UL
alert(chapter.closest('.contents')); // DIV
alert(chapter.closest('h1')); // null(h1은 li의 조상 요소가 아님)
</script>
요소.getElementsBy*
: 태그나 클래스 등을 이용해 원하는 노드를 찾음
: querySelector를 사용하는게 더 편리하고 문법이 짧아서 잘 사용하지 않음
- 요소.getElementsByTagName(tag)
: 주어진 태그에 해당하는 요소를 찾고 대응하는 요소를 담은 컬렉션을 반환
: tag에 *이 들어가면 모든 태그를 검색
- 요소.getElementsByClassName(className)
: class 속성 값을 기준으로 요소를 찾고 컬렉션을 반환
- 요소.getElementsByName(name)
: 문서 전체를 대상으로 name 속성 값을 기준으로 요소를 찾아 컬렉션을 반환
<table id="table">
<tr>
<td>나이:</td>
<td>
<label>
<input type="radio" name="age" value="young" checked> 18세 미만
</label>
<label>
<input type="radio" name="age" value="mature"> 18세 이상, 60세 미만
</label>
<label>
<input type="radio" name="age" value="senior"> 60세 이상
</label>
</td>
</tr>
</table>
<script>
let inputs = table.getElementsByTagName('input');
for (let input of inputs) {
alert( input.value + ': ' + input.checked );
}
</script>
<form name="my-form">
<div class="article">글</div>
<div class="long article">내용이 긴 글</div>
</form>
<script>
// name 속성을 이용해 검색
let form = document.getElementsByName('my-form')[0];
// fomr 내에서 클래스 이름을 이용해 검색
let articles = form.getElementsByClassName('article');
alert(articles.length); // 2. 클래스 속성값이 'article'인 요소는 2개입니다.
</script>
※ s를 빼먹지 말 것
: getElements -> 여기서 s를 빼먹는 실수가 잦다
살아있는 컬렉션
: getElementsBy로 시작하는 모든 메서드는 살아있는 컬렉션을 반환
: 문서에 변경이 있을 때마다 컬렉션이 자동으로 갱신되어 최신 상태를 유지함
: getSelectAll은 정적인 컬렉션을 반환
Refference
getElement*, querySelector*로 요소 검색하기
ko.javascript.info