jQuery로 하는 거의 모든 작업은 “무엇을 고를 것인가”에서 시작합니다. 고르는 일이 정확해지면 나머지는 메서드 하나를 붙이는 것으로 끝납니다. 이 글에서는 선택자를 넓게 잡았다가 점점 좁혀 가는 순서로, 기본 선택자부터 필터와 탐색 메서드, 체이닝까지 살펴봅니다.
1단계: CSS와 똑같은 세 가지 기본 선택자
jQuery 선택자의 가장 큰 장점은 새로 외울 것이 거의 없다는 점입니다. CSS에서 쓰던 표현을 따옴표 안에 그대로 넣으면 됩니다.
$('p') // 모든 <p> 태그
$('#mainNote') // id가 mainNote인 요소 하나
$('.note-card') // class가 note-card인 요소 전부
$('.note-card p') // 카드 안에 있는 모든 문단 (후손)
$('.note-card > p') // 카드의 바로 아래 문단만 (자식)
$('h3, h4') // 두 종류를 한꺼번에
여기서 기억할 규칙이 하나 있습니다. #은 문서에 하나뿐인 이름이라 결과가 최대 한 개지만, 태그와 클래스는 몇 개가 잡히든 한 덩어리로 묶여 돌아온다는 점입니다. 그래서 $('.note-card').hide()는 반복문 없이 카드 전체를 감춥니다. 순수 자바스크립트라면 querySelectorAll로 목록을 받은 뒤 forEach를 돌려야 하는 부분입니다.
2단계: 속성으로 더 좁히기
클래스가 붙어 있지 않은 요소를 골라야 할 때가 있습니다. 특히 폼 안의 입력칸이 그렇습니다. 이때는 대괄호 안에 속성 조건을 씁니다.
$('input[type="checkbox"]') // 체크박스만
$('a[target]') // target 속성이 있는 링크 전부
$('a[href^="/course"]') // href가 /course로 시작하는 링크
$('img[src$=".png"]') // src가 .png로 끝나는 이미지
$('a[href*="jquery"]') // href에 jquery가 들어간 링크
기호 세 개만 구분하면 됩니다. ^는 시작, $는 끝, *는 포함입니다. 여기 쓰인 $는 jQuery 함수와 아무 관련이 없고 “문자열의 끝”을 뜻하는 별개의 표시입니다.
3단계: 필터로 순서와 조건 지정하기
이미 고른 묶음에서 몇 번째만 남기고 싶다면 콜론으로 시작하는 필터를 붙입니다.
| 필터 | 고르는 대상 |
|---|---|
:first |
묶음의 첫 번째 요소 하나 |
:last |
묶음의 마지막 요소 하나 |
:even |
0, 2, 4번째 (0부터 셉니다) |
:odd |
1, 3, 5번째 |
:not(조건) |
조건에 맞지 않는 요소 |
:contains('글자') |
해당 글자를 품고 있는 요소 |
$('.note-card:first').addClass('featured');
$('#courseTable tr:even').css('background', '#f7f7f7');
$('.note-card:not(.draft)').show();
여기서 입문자가 거의 예외 없이 걸리는 지점이 :even입니다. 사람은 첫 번째 줄을 홀수로 세지만 jQuery는 0번부터 셉니다. 그래서 표의 첫 줄에 색을 넣고 싶으면 :odd가 아니라 :even을 써야 합니다. 줄무늬 색이 한 칸씩 밀려 보인다면 대부분 이 문제입니다.
4단계: 이미 선 자리에서 이동하는 탐색 메서드
선택자는 문서 전체에서 찾는 방식이고, 탐색 메서드는 지금 고른 요소를 기준으로 가족 관계를 따라 이동하는 방식입니다. 클릭된 버튼 하나를 기준으로 주변을 다룰 때 특히 유용합니다.
var $card = $('#note12');
$card.find('.tag'); // 카드 안쪽 모든 깊이에서 .tag 찾기
$card.children('p'); // 바로 아래 자식 중 문단만
$card.parent(); // 카드를 감싼 부모 하나
$card.closest('section');// 위로 올라가며 만나는 첫 section
$card.siblings(); // 나를 뺀 형제들
$card.eq(0); // 묶음에서 0번째 하나만
find와 children은 비슷해 보이지만 깊이가 다릅니다. children은 딱 한 층 아래만 보고, find는 몇 층이든 파고듭니다. 카드 안에 <div>로 한 번 더 감싼 태그가 있는데 children('.tag')로 찾으면 결과가 0개가 나옵니다.
그리고 결과가 0개여도 jQuery는 오류를 내지 않습니다. 조용히 아무 일도 하지 않을 뿐입니다. 선택이 제대로 됐는지 확인하려면 console.log($('.tag').length)로 개수를 먼저 찍어 보는 습관이 필요합니다.
5단계: 체이닝으로 한 줄에 이어 쓰기
jQuery 메서드는 대부분 작업을 마친 뒤 자기 자신을 다시 돌려줍니다. 그래서 점을 찍어 계속 이어 붙일 수 있고, 이것을 체이닝이라고 부릅니다.
$('#note12')
.addClass('active')
.find('.tag')
.css('color', '#c0392b')
.end()
.siblings()
.removeClass('active');
find로 안쪽에 들어가면 그 뒤 메서드는 모두 .tag에 적용됩니다. end()는 한 단계 전으로 되돌아오라는 뜻이라, 그 뒤의 siblings()는 다시 #note12를 기준으로 동작합니다. 체이닝이 길어지면 위 예시처럼 줄을 바꾸고 들여쓰기로 깊이를 표시해야 나중에 읽을 수 있습니다.
선택자를 익혔다면 다음은 고른 요소의 내용을 바꿀 차례입니다. jQuery DOM 조작으로 이어집니다. $의 정체가 아직 헷갈린다면 jQuery 입문을 먼저 확인하시기 바랍니다.
핵심 정리
- 기본 선택자 — CSS 문법을 그대로 쓰며, 여러 개가 잡혀도 반복문 없이 한 번에 처리됩니다.
- 속성 선택자 —
^시작,$끝,*포함으로 조건을 좁힙니다. - 필터 —
:even과:odd는 0부터 세므로 첫 줄이 짝수 취급을 받습니다. - 탐색 메서드 —
children은 한 층,find는 모든 깊이를 뒤집니다. - 조용한 실패 — 선택 결과가 0개여도 오류가 없으므로
length로 확인해야 합니다.