본문 바로가기

멋쟁이사자처럼_부트캠프/JavaScript

[멋쟁이사자처럼 부트캠프 TIL 회고] 백엔드 부트캠프 13기: Java 27일차 JavaScript 연동, 이벤트 핸들러

HTML과 JavaScript 연동하기

DOM : 구조

HTML, XML 문서를 프로그래밍적으로 다룰 수 있도록 문서의 구조를 객체(Object)로 표현한 모델.

웹 브라우저가 HTML 문서를 로드하면, DOM이라는 계층 구조로 문서를 나타내고 JavaScript 등을 사용해 이 구조를 조작할 수 있게 함.

 

트리 구조:
DOM은 문서의 계층적 구조를 표현합니다. HTML 문서가 DOM으로 변환되면, 다음과 같은 노드 트리(Node Tree)로 구성됩니다.

 

HTML:

<html>
  <head>
    <title>Page Title</title>
  </head>
  <body>
    <h1>Hello World</h1>
    <p>This is a paragraph.</p>
  </body>
</html>

 

DOM 트리:

Document
└── html
    ├── head
    │   └── title ("Page Title")
    └── body
        ├── h1 ("Hello World")
        └── p ("This is a paragraph.")

 

요소 간 관계:
DOM은 요소들 간의 부모-자식-형제 관계를 정의합니다.

  • <html>은 <head>와 <body>의 부모.
  • <head>와 <body>는 서로 형제.
  • <h1>과 <p>는 <body>의 자식.

DOM을 사용하면 JavaScript로 문서를 동적으로 변경하고 사용자와 상호작용할 수 있습니다.

 


HTML과 자바스크립트 이벤트 핸들러

이벤트 핸들러(Event Handler)는 사용자가 웹 페이지와 상호작용할 때(클릭, 입력, 스크롤 등) 실행되는 자바스크립트 함수입니다. 이벤트 핸들러는 특정 HTML 요소에서 발생하는 이벤트를 처리하기 위해 사용됩니다.

 

이벤트 핸들러 사용 방법

1. HTML 속성으로 이벤트 핸들러 지정

<button onclick="handleClick()">Click Me</button>
<script>
  function handleClick() {
    alert('Button clicked!');
  }
</script>

 

2. DOM 요소의 속성으로 이벤트 핸들러 등록

<button id="myButton">Click Me</button>
<script>
  const button = document.getElementById('myButton');
  button.onclick = function() {
    alert('Button clicked!');
  };
</script>

 

3. addEventListener 메서드로 이벤트 핸들러 등록 (추천 방식)

<button id="myButton">Click Me</button>
<script>
  const button = document.getElementById('myButton');
  button.addEventListener('click', () => {
    alert('Button clicked!');
  });
</script>
 
 

자주 쓰이는 HTML/JS 이벤트 목록

  1. 마우스 이벤트
    • click: 요소를 클릭할 때 발생.
    • dblclick: 요소를 더블 클릭할 때 발생.
    • mouseover: 마우스를 요소 위로 올릴 때 발생.
    • mouseout: 마우스를 요소 밖으로 뺄 때 발생.
    • mousedown: 마우스 버튼을 누를 때 발생.
    • mouseup: 마우스 버튼을 뗄 때 발생.
  2. 키보드 이벤트
    • keydown: 키를 누를 때 발생.
    • keyup: 키를 뗄 때 발생.
    • keypress: 키를 누를 때 발생 (권장되지 않음, keydown 사용).
  3. 폼 이벤트
    • submit: 폼이 제출될 때 발생.
    • change: 입력값이 변경될 때 발생.
    • input: 입력값이 변경될 때 발생(실시간).
    • focus: 요소가 포커스를 받을 때 발생.
    • blur: 요소가 포커스를 잃을 때 발생.
  4. 윈도우 이벤트
    • load: 페이지나 리소스가 모두 로드되었을 때 발생.
    • resize: 창 크기가 변경될 때 발생.
    • scroll: 스크롤할 때 발생.
    • unload: 페이지를 떠날 때 발생.
  5. 터치 이벤트 (모바일)
    • touchstart: 화면을 터치할 때 발생.
    • touchmove: 터치 상태에서 손가락을 움직일 때 발생.
    • touchend: 터치를 끝낼 때 발생.

 

이벤트 객체(Event Object)

이벤트 핸들러에 전달되는 이벤트 객체를 통해 이벤트에 대한 세부 정보를 확인할 수 있습니다.

<button id="myButton">Click Me</button>
<script>
  const button = document.getElementById('myButton');
  button.addEventListener('click', (event) => {
    console.log(event); // 이벤트 객체 출력
    console.log(event.target); // 이벤트가 발생한 요소
    console.log(event.type); // 이벤트 타입 (예: "click")
  });
</script>

 

이벤트 전파(Event Propagation)

이벤트가 발생하면 캡처링 단계버블링 단계를 거치면서 DOM 요소로 전파됩니다.

  • 캡처링 단계: 최상위 요소에서 시작해 이벤트가 목표 요소까지 전달됨.
  • 버블링 단계: 목표 요소에서 시작해 이벤트가 최상위 요소로 전달됨.

addEventListener의 세 번째 매개변수로 캡처링 여부를 설정할 수 있습니다:

element.addEventListener('click', handler, true); // 캡처링 단계에서 실행
element.addEventListener('click', handler, false); // 버블링 단계에서 실행 (기본값)

 

이벤트 취소

preventDefault() 메서드를 사용해 기본 동작을 막을 수 있습니다:

<a href="https://example.com" id="myLink">Go to Example</a>
<script>
  const link = document.getElementById('myLink');
  link.addEventListener('click', (event) => {
    event.preventDefault(); // 링크 클릭 시 페이지 이동 방지
    alert('Link clicked, but not navigating!');
  });
</script>

 

stopPropagation() 메서드를 사용해 이벤트 전파를 막을 수 있습니다:

element.addEventListener('click', (event) => {
  event.stopPropagation(); // 부모 요소로의 이벤트 전파 중단
});

 

이벤트 핸들러는 유저와의 상호작용을 다룰 때 필수적인 개념


JS로 숫자 카운터 만들기

<!DOCTYPE html>
<html>
  <head>
    <title>Parcel Sandbox</title>
    <meta charset="UTF-8" />
  </head>
  <body>
    <h2 id="number">0</h2>
    <div>
      <button id="increase">+1</button>
      <button id="decrease">-1</button>
    </div>
    <script src="03.js"></script>
  </body>
</html>
// 숫자 표시 요소 가져오기
const numberElement = document.getElementById("number");

// 버튼 가져오기
const increaseButton = document.getElementById("increase");
const decreaseButton = document.getElementById("decrease");

// 초기값 설정
let count = 0;

// 숫자 증가 함수
increaseButton.addEventListener("click", () => {
  count += 1; // 값 증가
  numberElement.textContent = count; // 화면에 업데이트
});

// 숫자 감소 함수
decreaseButton.addEventListener("click", () => {
  count -= 1; // 값 감소
  numberElement.textContent = count; // 화면에 업데이트
});

 

h2 와 button 태그에 id 값을 설정해주었는데,

이렇게 id 값을 설정 해주면 JavaScript 에서 쉽게 해당 DOM 을 선택 할 수 있다.

 

// 숫자 증가 함수
increaseButton.addEventListener("click", () => {
  count += 1; // 값 증가
  numberElement.textContent = count; // 화면에 업데이트
  console.log(`숫자 증가: ${count}`); // 로그 추가
});

// 숫자 감소 함수
decreaseButton.addEventListener("click", () => {
  count -= 1; // 값 감소
  numberElement.textContent = count; // 화면에 업데이트
  console.log(`숫자 감소: ${count}`); // 로그 추가
});

위와같이 로그 메세지를 띄우도록 수정할 수 있다.

 

console.log(number.innerText); // 내용 -> "0"
console.log(increase.offsetTop); // top 위치 -> 버튼의 위치 (픽셀 단위)
console.log(decrease.id); // id -> "decrease"

 

  • number.innerText:
    number 요소의 텍스트 내용을 가져옵니다. 이 경우, h2 태그 안에 있는 숫자(0)를 출력할 것입니다. 따라서 첫 번째 console.log는 0을 출력합니다.
  • increase.offsetTop:
    increase 버튼의 offsetTop은 해당 버튼의 상단 위치를 픽셀 단위로 반환합니다. 이는 해당 요소가 문서 상에서 얼마나 떨어져 있는지를 나타내는 값입니다. 예를 들어, 페이지에서 버튼이 100px 아래에 위치한다면 console.log(increase.offsetTop)은 100을 출력합니다.
  • decrease.id:
    decrease 버튼의 id 속성 값을 가져옵니다. 해당 버튼의 id는 "decrease"이므로, console.log(decrease.id)는 "decrease"를 출력합니다.

 

 


 

JavaScript를 이용해 이벤트 핸들링을 할 때의 문제점

  • 처리해야 할 이벤트도 다양해지고, 관리해야 할 상태값도 다양해지고, DOM 도 다양해지게 된다면, 이에 따라 업데이트를 하는 규칙도 많이 복잡해진다.
  • Ember, Backbone, AngularJS 등의 프레임워크가 만들어졌었는데, 이 프레임워크들은 작동방식이 각각 다르지만, 쉽게 설명하자면 자바스크립트의 특정 값이 바뀌면 특정 DOM의 속성이 바뀌도록 연결을 해주어서, 업데이트 하는 작업을 간소화해주는 방식으로 웹개발의 어려움을 해결해 주었다.