이벤트 처리
              
          2025. 3. 30. 22:40ㆍWeb Development/JavaScript
이벤트 처리
이벤트는 사용자의 행동(클릭, 키보드 입력 등)이나 프로그래밍적 변화(로딩 완료, 타이머 완료 등)에 반응하여 JavaScript 코드를 실행할 수 있게 해주는 메커니즘입니다.
이벤트 리스너 등록
요소에 이벤트 리스너(이벤트 핸들러)를 등록하는 방법입니다.
// 1. addEventListener 메서드 (권장 방법)
const button = document.querySelector('#myButton');
button.addEventListener('click', function(event) {
  console.log('버튼이 클릭되었습니다!');
  console.log('이벤트 객체:', event);
});
// 화살표 함수 사용
button.addEventListener('click', (event) => {
  console.log('화살표 함수 핸들러로 클릭 처리');
});
// 이벤트 리스너 제거
function clickHandler(event) {
  console.log('클릭 이벤트 발생!');
  // 한 번만 실행되고 제거
  event.currentTarget.removeEventListener('click', clickHandler);
}
button.addEventListener('click', clickHandler);
// 2. 이벤트 속성 (on + 이벤트 이름)
const secondButton = document.querySelector('#secondButton');
secondButton.onclick = function(event) {
  console.log('onclick 속성 사용');
};
// 주의: 이전 핸들러를 덮어씀
secondButton.onclick = function(event) {
  console.log('새로운 onclick 핸들러가 이전 것을 대체함');
};
// 3. 인라인 이벤트 속성 (HTML에 직접 작성 - 권장하지 않음)
// <button onclick="console.log('인라인 이벤트')">클릭</button>
주요 이벤트 유형
JavaScript에서 다룰 수 있는 다양한 이벤트 유형들입니다.
// 마우스 이벤트
element.addEventListener('click', () => console.log('클릭'));
element.addEventListener('dblclick', () => console.log('더블 클릭'));
element.addEventListener('mousedown', () => console.log('마우스 버튼 누름'));
element.addEventListener('mouseup', () => console.log('마우스 버튼 뗌'));
element.addEventListener('mousemove', (e) => console.log(`마우스 이동: ${e.clientX}, ${e.clientY}`));
element.addEventListener('mouseover', () => console.log('마우스 요소 위로 이동'));
element.addEventListener('mouseout', () => console.log('마우스 요소 밖으로 이동'));
element.addEventListener('contextmenu', (e) => {
  e.preventDefault(); // 기본 컨텍스트 메뉴 방지
  console.log('우클릭');
});
// 키보드 이벤트
document.addEventListener('keydown', (e) => console.log(`키 누름: ${e.key}`));
document.addEventListener('keyup', (e) => console.log(`키 뗌: ${e.key}`));
document.addEventListener('keypress', (e) => console.log(`문자 입력: ${e.key}`));
// 폼 이벤트
const form = document.querySelector('form');
form.addEventListener('submit', (e) => {
  e.preventDefault(); // 기본 제출 동작 방지
  console.log('폼 제출됨');
});
const input = document.querySelector('input');
input.addEventListener('focus', () => console.log('포커스 얻음'));
input.addEventListener('blur', () => console.log('포커스 잃음'));
input.addEventListener('input', (e) => console.log(`입력값 변경: ${e.target.value}`));
input.addEventListener('change', (e) => console.log(`값 변경 확정: ${e.target.value}`));
// 문서 및 윈도우 이벤트
document.addEventListener('DOMContentLoaded', () => console.log('DOM 로드 완료'));
window.addEventListener('load', () => console.log('페이지 완전히 로드됨'));
window.addEventListener('resize', () => console.log('윈도우 크기 변경'));
window.addEventListener('scroll', () => console.log('스크롤 발생'));
window.addEventListener('beforeunload', (e) => {
  // 페이지 나가기 전 확인 (현대 브라우저에서는 제한적)
  e.preventDefault();
  e.returnValue = '';
});
// 터치 이벤트 (모바일)
element.addEventListener('touchstart', () => console.log('터치 시작'));
element.addEventListener('touchend', () => console.log('터치 종료'));
element.addEventListener('touchmove', () => console.log('터치 이동'));
이벤트 객체
이벤트 핸들러에 자동으로 전달되는 이벤트 객체를 통해 이벤트 관련 정보에 접근할 수 있습니다.
document.querySelector('button').addEventListener('click', function(event) {
  // 기본 이벤트 정보
  console.log('이벤트 타입:', event.type); // "click"
  console.log('이벤트 타겟:', event.target); // 실제 클릭된 요소
  console.log('현재 타겟:', event.currentTarget); // 이벤트 리스너가 연결된 요소
  
  // 마우스 이벤트 정보
  console.log('클릭 좌표 (화면):', event.clientX, event.clientY);
  console.log('클릭 좌표 (페이지):', event.pageX, event.pageY);
  console.log('Alt키 누름:', event.altKey);
  console.log('Ctrl키 누름:', event.ctrlKey);
  console.log('Shift키 누름:', event.shiftKey);
  console.log('마우스 버튼:', event.button); // 0: 좌클릭, 1: 휠, 2: 우클릭
  
  // 이벤트 제어
  event.preventDefault(); // 기본 동작 방지 (예: 링크 클릭 시 페이지 이동 방지)
  event.stopPropagation(); // 이벤트 버블링 중단
});
// 키보드 이벤트 특수 정보
document.addEventListener('keydown', function(event) {
  console.log('누른 키:', event.key); // 키 이름 ("a", "Enter" 등)
  console.log('키 코드:', event.keyCode); // 키 코드 (deprecated)
  console.log('Alt키 누름:', event.altKey);
  console.log('Ctrl키 누름:', event.ctrlKey);
  console.log('Shift키 누름:', event.shiftKey);
  
  // 특정 키 조합 감지
  if (event.ctrlKey && event.key === 's') {
    event.preventDefault(); // 브라우저 기본 저장 동작 방지
    console.log('Ctrl+S 조합 감지');
    // 저장 처리 코드
  }
});
이벤트 전파(Event Propagation)
DOM에서 이벤트는 캡처링(capturing)과 버블링(bubbling)이라는 두 단계로 전파됩니다.
/* HTML 구조 예시:
<div id="outer">
  <div id="inner">
    <button id="button">클릭</button>
  </div>
</div>
*/
// 이벤트 버블링 (기본): 하위 요소에서 상위 요소로 이벤트가 전파됨
document.querySelector('#button').addEventListener('click', (e) => {
  console.log('버튼 클릭됨');
});
document.querySelector('#inner').addEventListener('click', (e) => {
  console.log('inner div 클릭됨 (버블링)');
});
document.querySelector('#outer').addEventListener('click', (e) => {
  console.log('outer div 클릭됨 (버블링)');
});
// 이벤트 캡처링: 상위 요소에서 하위 요소로 이벤트가 전파됨
document.querySelector('#outer').addEventListener('click', (e) => {
  console.log('outer div 클릭됨 (캡처링)');
}, true); // 세 번째 인자를 true로 설정하면 캡처링 단계에서 실행
document.querySelector('#inner').addEventListener('click', (e) => {
  console.log('inner div 클릭됨 (캡처링)');
}, true);
document.querySelector('#button').addEventListener('click', (e) => {
  console.log('버튼 클릭됨 (캡처링)');
}, true);
// 버튼 클릭 시 콘솔 출력 순서:
// 1. "outer div 클릭됨 (캡처링)" (캡처링 단계)
// 2. "inner div 클릭됨 (캡처링)" (캡처링 단계)
// 3. "버튼 클릭됨 (캡처링)" (캡처링 단계)
// 4. "버튼 클릭됨" (타겟 단계)
// 5. "inner div 클릭됨 (버블링)" (버블링 단계)
// 6. "outer div 클릭됨 (버블링)" (버블링 단계)
// 이벤트 전파 중단
document.querySelector('#inner').addEventListener('click', (e) => {
  console.log('inner div 클릭됨 (버블링)');
  e.stopPropagation(); // 이벤트 버블링 중단
  // outer div의 이벤트 핸들러는 실행되지 않음
});
이벤트 위임(Event Delegation)
부모 요소에 이벤트 리스너를 등록하여 자식 요소들의 이벤트를 효율적으로 처리하는 패턴입니다.
// 비효율적인 방식: 각 버튼마다 이벤트 리스너 등록
// document.querySelectorAll('.button').forEach(button => {
//   button.addEventListener('click', () => {
//     console.log('버튼 클릭:', button.textContent);
//   });
// });
// 이벤트 위임: 부모 요소에 한 번만 이벤트 리스너 등록
document.querySelector('#buttons-container').addEventListener('click', (e) => {
  // 클릭된 요소가 버튼인지 확인
  if (e.target.matches('.button')) {
    console.log('버튼 클릭:', e.target.textContent);
  }
  
  // 또는 다른 방식으로 확인
  if (e.target.className === 'button') {
    console.log('버튼 클릭:', e.target.textContent);
  }
  
  // 데이터 속성으로 추가 정보 활용
  if (e.target.matches('[data-action]')) {
    const action = e.target.dataset.action;
    console.log(`액션 "${action}" 실행`);
    
    // 액션에 따른 다른 처리
    switch(action) {
      case 'save':
        saveData();
        break;
      case 'load':
        loadData();
        break;
      case 'delete':
        deleteData();
        break;
    }
  }
});
// 동적으로 추가된 요소에도 자동으로 적용됨
const newButton = document.createElement('button');
newButton.className = 'button';
newButton.textContent = '새 버튼';
document.querySelector('#buttons-container').appendChild(newButton);
커스텀 이벤트
자신만의 이벤트를 생성하고 발생시킬 수 있습니다.
// 커스텀 이벤트 생성 및 발생
const button = document.querySelector('#myButton');
// 이벤트 리스너 등록
button.addEventListener('userLogin', (e) => {
  console.log('사용자 로그인 이벤트 발생!');
  console.log('로그인 유저:', e.detail.username);
  console.log('로그인 시간:', e.detail.time);
});
// 이벤트 발생시키기
const loginEvent = new CustomEvent('userLogin', {
  detail: {
    username: 'user123',
    time: new Date().toLocaleTimeString()
  },
  bubbles: true,
  cancelable: true
});
button.dispatchEvent(loginEvent);
// 간단한 커스텀 이벤트 (데이터 없이)
const simpleEvent = new Event('simpleTrigger', {
  bubbles: true,
  cancelable: true
});
document.dispatchEvent(simpleEvent);
document.addEventListener('simpleTrigger', () => {
  console.log('간단한 이벤트 발생');
});
이벤트 처리:
- addEventListener로 이벤트 리스너 등록
 - 다양한 이벤트 유형 처리 (클릭, 키보드, 폼, 로드 등)
 - 이벤트 객체를 통한 상세 정보 접근
 - 이벤트 전파 (캡처링, 버블링)와 이벤트 위임
 - 커스텀 이벤트 생성 및 발생
 
'Web Development > JavaScript' 카테고리의 다른 글
| 비동기 프로그래밍 (0) | 2025.03.30 | 
|---|---|
| 실전 DOM 조작 예제 (0) | 2025.03.30 | 
| 요소 선택과 조작 (0) | 2025.03.30 | 
| DOM 조작 (0) | 2025.03.30 | 
| 배열 (0) | 2025.03.30 |