자바스크립트: 선택자 여러 개를 한 번에 다루는 마법 같은 방법! (querySelector, forEach, 이벤트 위임)

자바스크립트: 선택자 여러 개를 한 번에 다루는 마법 같은 방법! (querySelector, forEach, 이벤트 위임)


검색 설명: 자바스크립트 DOM 조작, 더 이상 노가다는 그만! querySelectorAll, forEach, 이벤트 위임으로 여러 요소를 효율적으로 다루는 비법을 알려드립니다.


안녕하세요, 개발자 여러분! 자바스크립트에서 웹 요소를 다룰 때, 특정 작업을 여러 요소에 한 번에 적용해야 하는 경우가 많습니다. 예를 들어, 여러 개의 버튼에 동일한 클릭 이벤트를 추가하거나, 특정 클래스를 가진 모든 문단의 텍스트 색상을 변경하는 등이죠.

이럴 때 유용하게 사용되는 방법들을 예제를 통해 자세히 살펴보겠습니다.


1. querySelectorAll()forEach() 활용 (가장 일반적이고 권장되는 방법)

document.querySelectorAll()은 CSS 선택자를 사용하여 문서 내에서 조건에 맞는 모든 요소(NodeList)를 반환합니다. 이 NodeList는 배열과 유사한 객체이므로, forEach() 메서드를 사용하여 각 요소에 접근하고 원하는 함수를 적용할 수 있습니다.

예제: 여러 개의 버튼에 클릭 이벤트 추가하기

HTML 코드:


<button class="my-button">버튼 1</button>
<button class="my-button">버튼 2</button>
<button class="my-button">버튼 3</button>
<div id="message"></div>

자바스크립트 코드:


// 1. 모든 'my-button' 클래스를 가진 요소를 선택합니다.
const buttons = document.querySelectorAll('.my-button');
const messageDiv = document.getElementById('message');

// 2. 선택된 각 버튼에 대해 반복하면서 이벤트 리스너를 추가합니다.
buttons.forEach(button => {
  button.addEventListener('click', function() {
    // `this`는 클릭된 해당 버튼 요소를 가리킵니다.
    console.log(`${this.textContent}이(가) 클릭되었습니다.`);
    messageDiv.textContent = `${this.textContent}이(가) 방금 클릭됨!`;
    this.style.backgroundColor = '#4CAF50'; // 클릭된 버튼의 배경색 변경
    this.style.color = 'white';
  });
});

설명:

  • document.querySelectorAll('.my-button'): 문서 내에서 my-button 클래스를 가진 모든 <button> 요소를 선택하여 NodeList 형태로 buttons 변수에 저장합니다.
  • buttons.forEach(button => { ... });: NodeListforEach 메서드를 지원하므로, 각 button 요소에 대해 지정된 콜백 함수를 실행합니다.
  • button.addEventListener('click', function() { ... });: 각 버튼에 'click' 이벤트 리스너를 추가합니다. 이벤트가 발생하면 콜백 함수가 실행됩니다.
  • this: 이 콜백 함수 내에서 this실제로 클릭된 개별 <button> 요소를 가리킵니다. 이를 통해 해당 버튼의 텍스트(textContent)나 스타일(style)을 개별적으로 조작할 수 있습니다.

2. getElementsByClassName(), getElementsByTagName() 활용 (구형 브라우저 호환성 및 유사 배열 객체)

getElementsByClassName() (클래스 이름으로 선택)이나 getElementsByTagName() (태그 이름으로 선택)은 HTMLCollection이라는 유사 배열 객체(Array-like object)를 반환합니다. HTMLCollectionforEach() 메서드를 직접 지원하지 않을 수 있습니다 (구형 브라우저). 이 경우에는 Array.from()을 사용하여 배열로 변환하거나, 전통적인 for 루프를 사용해야 합니다.

예제: 모든 <li> 태그에 스타일 적용하기

HTML 코드:


<ul id="myList">
  <li>항목 1</li>
  <li>항목 2</li>
  <li>항목 3</li>
</ul>

자바스크립트 코드:


const listItems = document.getElementsByTagName('li'); // HTMLCollection 반환

// 방법 1: Array.from()을 사용하여 배열로 변환 후 forEach 사용 (권장)
Array.from(listItems).forEach(item => {
  item.style.backgroundColor = '#f0f0f0';
  item.style.padding = '5px';
  item.style.marginBottom = '5px';
});

/*
// 방법 2: 전통적인 for 루프 사용
for (let i = 0; i < listItems.length; i++) {
  listItems[i].style.backgroundColor = '#e0e0e0';
  listItems[i].style.padding = '5px';
  listItems[i].style.marginBottom = '5px';
}
*/

설명:

  • document.getElementsByTagName('li'): 문서 내 모든 <li> 태그를 선택하여 HTMLCollection 객체로 listItems 변수에 저장합니다.
  • Array.from(listItems): HTMLCollection을 실제 자바스크립트 배열로 변환하여 forEach와 같은 배열 메서드를 사용할 수 있게 합니다.

팁: 특별한 이유가 없다면 querySelectorAll()이 더 유연하고 직관적인 CSS 선택자 문법을 사용하므로, 대부분의 경우 querySelectorAll()을 사용하는 것을 권장합니다.


3. 고유 ID를 가진 여러 요소에 함수 적용 (드물지만 가능한 경우)

보통 ID는 문서 내에서 고유해야 하지만, 만약 여러 요소에 대해 각각 고유한 ID를 부여하고 그 ID들을 배열로 관리하는 경우에도 각 요소에 함수를 적용할 수 있습니다. 이는 자동화된 ID 부여 시스템 등 특정 상황에서 사용될 수 있습니다.

예제: 특정 ID 패턴을 가진 요소들에 텍스트 변경하기

HTML 코드:


<p id="item-text-1">첫 번째 텍스트</p>
<p id="item-text-2">두 번째 텍스트</p>
<p id="item-text-3">세 번째 텍스트</p>

자바스크립트 코드:


const itemIds = ['item-text-1', 'item-text-2', 'item-text-3'];

itemIds.forEach(id => {
  const element = document.getElementById(id);
  if (element) { // 해당 ID를 가진 요소가 실제로 존재하는지 확인
    element.textContent += ' (변경됨!)';
    element.style.color = 'blue';
  }
});

설명:

  • 미리 정의된 ID 배열을 순회하면서 document.getElementById()를 통해 개별 요소에 접근하여 함수를 적용합니다.

4. 다양한 선택자를 한 번에 제어하기 (querySelectorAll의 강력함)

querySelectorAll()은 단일 선택자뿐만 아니라 콤마(,)로 구분하여 여러 개의 선택자를 한 번에 지정할 수 있습니다. 이는 ID, 클래스, 태그 이름, 심지어 name 속성까지도 결합하여 원하는 모든 요소를 선택할 수 있게 해줍니다.

예제: ID, 클래스명, name 속성을 가진 요소들을 한 번에 제어

HTML 코드:


<input type="text" id="myInput" value="ID 입력 필드">
<div class="info-box">정보 상자 1</div>
<p class="info-box">정보 상자 2</p>
<input type="radio" name="option" value="a"> 옵션 A
<input type="radio" name="option" value="b"> 옵션 B
<span id="resultMessage"></span>

자바스크립트 코드:


const targets = document.querySelectorAll('#myInput, .info-box, [name="option"]');
const resultMessageSpan = document.getElementById('resultMessage');

let count = 0;
targets.forEach(element => {
  // 각 요소의 태그 이름과 속성(ID/클래스/name)에 따라 다른 작업 수행
  if (element.tagName === 'INPUT' && element.id === 'myInput') {
    element.value = 'ID로 제어됨!';
    element.style.border = '2px solid blue';
    console.log(`ID 선택자: ${element.id} 제어 완료!`);
  } else if (element.classList.contains('info-box')) {
    element.style.backgroundColor = '#e6ffe6';
    element.textContent += ' (클래스로 제어됨!)';
    console.log(`클래스 선택자: ${element.className} 제어 완료!`);
  } else if (element.tagName === 'INPUT' && element.name === 'option') {
    element.checked = true; // 라디오 버튼 선택
    console.log(`Name 속성 선택자: ${element.name} 값 ${element.value} 제어 완료!`);
  }
  count++;
});

resultMessageSpan.textContent = `총 ${count}개의 요소가 제어되었습니다.`;

설명:

  • document.querySelectorAll('#myInput, .info-box, [name="option"]'):
    • #myInput: ID가 myInput인 요소 (단 하나)
    • .info-box: 클래스가 info-box인 모든 요소
    • [name="option"]: name 속성 값이 option인 모든 요소
    위 세 가지 조건을 만족하는 모든 요소를 한 번에 선택하여 NodeList로 반환합니다.
  • forEach 루프 안에서 각 elementtagName, id, classList.contains(), name 속성 등을 활용하여 어떤 선택자로 선택된 요소인지 구분하고, 그에 맞는 특정 작업을 수행할 수 있습니다.

이 방법은 특정 그룹의 요소들을 한 번에 선택하여 공통적인 작업을 수행하거나, 선택된 요소들 안에서 조건에 따라 다른 작업을 유연하게 적용할 때 매우 유용합니다.


5. 이벤트 위임(Event Delegation) 활용 (효율적인 이벤트 처리)

수십 개 또는 수백 개의 요소에 각각 이벤트 리스너를 추가하는 것은 성능에 부담을 줄 수 있습니다. 이럴 때는 이벤트 위임이라는 기법을 사용하는 것이 훨씬 효율적입니다. 부모 요소에 단 하나의 이벤트 리스너를 추가하고, 실제 이벤트가 발생한 자식 요소를 식별하여 처리하는 방식입니다.

예제: 목록의 각 항목 클릭 시 메시지 표시 (이벤트 위임)

HTML 코드:


<ul id="parent-list">
  <li><a href="#" class="list-item">링크 항목 A</a></li>
  <li><a href="#" class="list-item">링크 항목 B</a></li>
  <li><a href="#" class="list-item">링크 항목 C</a></li>
  <li><a href="#" class="list-item">링크 항목 D</a></li>
</ul>
<div id="event-message"></div>

자바스크립트 코드:


const parentList = document.getElementById('parent-list');
const eventMessageDiv = document.getElementById('event-message');

// 부모 요소에만 이벤트 리스너를 추가합니다.
parentList.addEventListener('click', function(event) {
  // 클릭된 요소가 'list-item' 클래스를 가진 'A' 태그인지 확인합니다.
  if (event.target.matches('.list-item')) {
    event.preventDefault(); // 링크의 기본 동작(페이지 이동) 방지
    console.log(`${event.target.textContent}이(가) 클릭되었습니다.`);
    eventMessageDiv.textContent = `클릭된 항목: ${event.target.textContent}`;
    event.target.style.fontWeight = 'bold'; // 클릭된 항목만 글씨를 굵게
  }
});

설명:

  • parentList.addEventListener('click', function(event) { ... });: 개별 <li> 또는 <a> 태그가 아닌, 이들의 부모인 <ul>에 클릭 이벤트 리스너를 하나만 추가합니다.
  • event.target: 실제 클릭 이벤트가 발생한 가장 하위의 DOM 요소를 가리킵니다.
  • event.target.matches('.list-item'): 클릭된 요소가 .list-item 클래스를 가지고 있는지 확인하여, 우리가 원하는 요소에만 동작을 적용합니다.
  • 이벤트 위임은 동적으로 추가되는 요소에도 자동으로 이벤트 처리를 적용할 수 있다는 장점도 있습니다.

마무리하며

자바스크립트에서 여러 선택자를 이용하여 함수를 적용하는 방법은 다양하며, 각각의 장단점이 있습니다.

  • querySelectorAll() + forEach(): 대부분의 상황에서 가장 직관적이고 유연하며 권장되는 방법입니다. 다양한 CSS 선택자를 사용하여 ID, 클래스, 태그명, 심지어 속성 선택자까지 한 번에 활용할 수 있다는 강력한 장점이 있습니다.
  • getElementsBy... 계열 메서드: 구형 브라우저 호환성을 고려하거나 특정 태그/클래스에만 접근할 때 사용할 수 있으나, Array.from() 변환이 필요할 수 있습니다.
  • 이벤트 위임: 수많은 요소에 이벤트를 처리해야 할 때 성능상 매우 효율적이며, 동적 요소에도 자동으로 적용됩니다.

이 예제들을 통해 여러분의 자바스크립트 DOM 조작 능력이 한층 더 향상되기를 바랍니다! 혹시 다른 방식으로 요소를 제어해야 할 때 궁금한 점이 있다면 언제든지 질문해주세요.


#자바스크립트 #JavaScript #DOM조작 #querySelectorAll #forEach #addEventListener #이벤트위임 #프론트엔드 #웹개발 #코딩 #JavaScript_tutorial #Web_Development #DOM_manipulation #CSS_selector

댓글 없음:

댓글 쓰기

댓글 폭탄 해결! 자바스크립트 댓글 접기/펼치기로 가독성 200% 높이는 법(Solve Comment Chaos: Elevate Readability 200% with JS Comment Folding/Unfolding)

내 웹사이트에 적용! 초간단 자바스크립트 댓글 펼치기/숨기기 튜토리얼 내 웹사이트에 적용! 초간단 자바스크립트 댓글 펼치기/숨기기 튜토...