자바스크립트
[자바스크립트] DOM, 이벤트
front-hyun
2023. 4. 13. 18:46
내부에서 스크립트 사용
<script> 태그는 HTML문서 내부에서 자바스크립트를 사용할 수 있게 해줍니다.
내부에서 스크립트를 사용하는 방식은 스크립트의 사용량이 간단할 때 사용합니다.
스크립트량이 많아지면, 외부에 스크립트파일을 만들어서 불러오기 형식으로 쓰는게 좋습니다.
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<h1> HTML 내부에서 자바스크립트 실행 </h1>
<script> // HTML 문서에서 JS 사용
alert("안녕하세요. 알람 입니다.") // JS 함수
</script>
</body>
</html>
외부 스크립트 사용
자바스크립트를 사용하는 언어를 따로 파일로 생성해서 저장할 수 있습니다.
따로 저장한 파일을 src 속성을 통해 HTML 문서 내부에 불러와서 사용할 수 있습니다.
<script src="절대경로 / 상대경로 / URL"></script>
<script src="/local/project/script.js"></script>
DOM
- Document Object Model(문서 객체 모델)
- HTML 페이지에 태그를 추가, 수정, 제거할 수 있습니다.
- 넓은 의미로 웹 브라우저가 HTML 페이지를 인식하는 방법, 좁은 의미로는 document 객체와 관련된 객체의 집합입니다.
- 웹 브라우저에 HTML 파일을 끌어다 놓으면 웹 브라우저는 HTML 파일을 분석해 화면에 출력합니다. 이때 웹 브라우저가 HTML 파일을 분석하고 출력하는 방식이 DOM입니다.
문서 객체란?
-HTML 태그를 자바스크립트에서 사용할 수 있는 객체로 만든 것입니다.
-문서 객체를 조작한다는 말은 태그를 조작한다는 말과 같습니다.
-문서 객체를 조작하면 태그 내부의 글자, 스타일, 속성을 변경할 수 있습니다.
DOM TREE
- 각 요소를 노드라고 하며, 요소 노드와 텍스트 노드로 구분합니다.
- h1 태그와 script 태그처럼 요소를 생성하는 노드를 요소 노드라고 합니다.
- 화면에 출력되는 문자열인 "My header", "My title" 등은 텍스트 노드라고 합니다.

주요 노드 타입

노드 선택하기
모든 노드 탐색
| parentNode | 부모 노드 반환 |
| childNodes | 모든 자식 노드 반환 |
| firstChild | 첫 번째 자식 노드 반환 |
| lastChild | 마지막 자식 노드 반환 |
| previousSibling | 이전 형제 노드 반환 |
| nextSibling | 다음 형제 노드 반환 |
요소 노드 탐색
| parentElement | 부모 요소 노드 반환 |
| children | 자식 요소 노드 반환 |
| firstElementChild | 첫 번째 자식 요소 노드 반환 |
| lastElementChild | 마지막 자식 요소 노드 반환 |
| previousElementSibling | 이전 요소 노드 반환 |
| nextElementSibling | 다음 요소 노드 노드 반환 |
메서드로 노드 선택하기
- 속성값과 태그명 사용하기 - get 메서드
| getElementById(<id 속성값>) | id 속성값과 일치하는 요소 노드를 1개만 선택합니다. |
| getElementsByClassName(<class 속성값>) | class 속성값과 일치하는 요소 노드를 모두 선택합니다. |
| getElementsByTagName(<태그명>) | 태그명과 일치하는 요소 노드를 모두 선택합니다. |
- CSS 선택자 사용하기 - query 메서드
-script 태그는 <body>의 가장 마지막에 위치해야 합니다.
| querySelector(<CSS 선택자>) | 매개변수로 넘어오는 CSS 선택자에 해당하는 노드를 1개만 선택합니다. 매개변수로 전달한 CSS 선택자로 선택되는 "첫 번째 태그"만 선택합니다. |
| querySelectorAll(<CSS 선택자>) | 매개변수로 넘어오는 CSS 선택자에 해당하는 노드를 모두 선택합니다. |
<body>
<h1> h1 태그 </h1>
<h2> h2 태그 </h2>
<script>
//h1 태그의 배경 색상 변경
document.querySelector('h1').style.backgroundColor="red";
//h2 태그의 글자 색상 변경
document.querySelector('h2').style.color="red";
</script>
</body>

노드 조작하기 - 콘텐츠 조작하기
| textContent | 요소 노드의 모든 텍스트에 접근합니다. |
| innerText | 요소 노드의 텍스트 중 웹 브라우저에 표시되는 텍스트에만 접근합니다. |
| innerHTML | 요소 노드의 텍스트 중 HTML 태그를 포함한 텍스트에만 접근합니다. 문서 객체 내부의 글자를 나타냅니다 |
- 조작시 접근한 노드의 콘텐츠를 가져올 뿐아니라 속성에 값 할당 시 각 노드의 콘텐츠를 바꿀수 있습니다.
<body>
<h1 id="header"> header 1 </h1>
<script>
const header=document.getElementById('header');
const originText=header.innerHTML;
header.innerHTML="자바스크립트로 변경<br>";
header.innerHTML+="원래는"+originText;
console.log(header.innerHTML);
</script>
</body>

노드 조작하기 - 스타일 조작하기
<노드>.style.<css 속성명> = <속성값>;
<p id="text">text</p>
<script>
const pE1 = document.querySelector("p"); // 노드 선택하기
pE1.style.color = "red";
</script>

노드 조작하기 - 클래스 속성 조작하기
//추가
<노드>.classList.add("class속성값");
//삭제
<노드>.classList.remove("class속성값");
//추가와 삭제 반복
<노드>.classList.toggle("class속성값");
setInterval() 함수
- 웹페이지의 특정 부분을 주기적으로 업데이트해줘야 하거나, 어떤 API로 부터 변경된 데이터를 주기적으로 받아와야 할 때 자바스크립트의 setInterval() 함수를 사용합니다.
- setInterval() 함수는 어떤 코드를 일정한 시간 간격을 두고 반복해서 실행하고 싶을 때 사용합니다.
- 함수 API는 setTimeout() 함수와 대동소이한데요. 첫번째 인자로 실행할 코드를 담고 있는 함수를 받고, 두번째 인자로 반복 주기를 밀리초(ms) 단위로 받습니다.
<div onclick="alert('클릭했습니다1.')">클릭</div>
<div onclick="view()">클릭</div>
<script>
function view() {
alert("클릭했습니다2.");
}
</script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/* 스타일로 텍스트의 색상과 위치 변경 */
.red-color {
color: red;
}
.fz20 {
font-size: 20px;
}
</style>
</head>
<body>
<p id="text"> text </p>
<script>
function change(){
const pEl=document.querySelector("#text");
pEl.classList.toggle("red-color");
pEl.classList.toggle("fz20");
}
setInterval(change,1000);
</script>
</body>
</html>
[실습 3]

이벤트
- 마우스 이벤트, 키보드 이벤트, 포커스 이벤트, 폼 이벤트가 있습니다.
- 웹페이지에서 마우스를 클릭했을 때, 키를 입력했을 때, 특정요소에 포커스가 이동되었을 때 어떤 사건을 발생시키는 것입니다.
이벤트 등록
1. 인라인 방식
- 인라인 이벤트 모델은 HTML 태그 내부에서 이벤트를 연결하는 방법입니다.
- 웹 페이지의 가장 기본적인 이벤트 연결 방식으로 HTML 태그 내부에 자바스크립트 코드를 넣어 이벤트를 실행합니다.
<태그명 on이벤트 = 자바스크립트 코드> </태그명>
//1번째 예시
<div onclick="alert('클릭했습니다1.')">클릭</div>
<div onclick="view()">클릭</div>
<script>
function view() {
alert("클릭했습니다2.");
}
</script>
//2번째 예시
<button onClick="clickEvent()"> 클릭 </button>
<script>
function clickEvent(){
alert("click");
}
</script>

2. 프로퍼티 리스너
- 프로퍼티 리스너 방식은 이벤트 대상에 해당하는 객체의 프로퍼티로 이벤트를 등록하는 방식입니다.
- 인라인 방식에 비해서 HTML과 JavaScript를 분리할 수 있다는 점에서 선호되는 방식이지만 뒤에서 배울 addEventListener 방식을 추천합니다.
<body>
<button> 클릭 </button>
<script>
const btnEl=document.querySelector("button");
btnEl.onclick=function(){
alert("click");
}
</script>
</body>
3. 이벤트 등록 메서드
<노드>.addEventListener("<이벤트 타입>", <이벤트 함수>);
<body>
<button> 클릭 </button>
<script>
const btnEl=document.querySelector("button");
btnEl.addEventListener("click", ()=>{alert("button Click");});
</script>
</body>

[실습 4] 버튼 클릭 시, "아기사자 파이팅"이 사라지도록 코드를 작성하세요.
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<input type="button" id="hider" value="Text를 숨기려면 클릭하세요." />
<div id="cheerup">아기사자 파이팅</div>
<script>
const btnEl=document.getElementById("hider");
btnEl.addEventListener("click",
()=>{document.getElementById("cheerup").style.display="none";});
</script>
</body>
</html>


[실습 5] 사용자가 입력한 숫자에 해당하는 단어를 출력하는 프로그램을 작성하세요.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Number to Word Converter</h1>
<input type="text" id="numberInput" placeholder="숫자를 입력하세요.">
<button id="convertButton">변환</button>
<p id="output"></p>
<script src="script.js"></script>
</body>
</html>
// numberInput, convertButton, output 요소를 가져옵니다.
const convertButton = document.getElementById("convertButton"); // 변환 버튼
const output = document.getElementById('output'); // 출력될 문자열
const numberInput = document.getElementById('numberInput'); // 입력될 숫자
// output 문자열 출력해줄 함수 정의
function outputText(sub) {
if (sub == 1) output.textContent = "하나";
else if (sub == 2) output.textContent = "둘";
else if (sub == 3) output.textContent = "셋";
else output.textContent = "해당하는 숫자에 대한 단어가 없습니다.";
}
// convertButton에 click 이벤트에 대한 이벤트 핸들러를 등록합니다.
convertButton.addEventListener("click", () => {
let subText = numberInput.value; // numberInput에서 입력한 값을 가져옵니다.
outputText(subText); // number에 해당하는 단어를 출력합니다.
});
// numberInput에 keydown 이벤트에 대한 이벤트 핸들러를 등록합니다.
numberInput.addEventListener("keydown", (event) => {
if (event.key === "Enter") {
let subText = numberInput.value; // 눌린 키의 코드를 가져옵니다.
outputText(subText); // 엔터 키를 눌렀을 때 convertButton을 클릭한 것과 같은 효과를 냅니다.
}
});


노드 추가/삭제
노드 생성(노드 추가)

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="homzzang">
<p id="p1">hyuna</p>
<p id="p2">tistory</p>
</div>
<script>
var p = document.createElement("p"); // P요소(=노드) 생성
var intro = document.createTextNode("홈페이지 제작관리"); // P요소에 넣은 내용 (= 텍스트노드 생성)
p.appendChild(intro); // P요소에 내용 넣기
var hz = document.getElementById("homzzang"); // 부모요소
hz.appendChild(p); // 부모요소에 생성한 P 요소 추가
</script>
</body>
</html>
노드 삭제

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div id="homzzang">
<p id="p1">hyuna</p>
<p id="p2">tistory</p>
</div>
<script>
var hz = document.getElementById("homzzang"); // 부모요소
var p1 = document.getElementById("p1"); // 자식요소 (= 삭제할 요소)
hz.removeChild(p1); // 부모요소에서 자식요소 제거
</script>
</body>
</html>
이벤트와 this
- 결과적으로 this는 어떤 내부에서 쓰였는지가 가장 중요합니다.
- 일반 함수 안에서는 window를, 생성자 함수로 만든 객체의 메소드에서는 자기 자신의 객체를, 이벤트리스너 안에서 사용된 this는 e.currentTarget을 나타냅니다. (이벤트리스너에서 따로 만든 함수는 일반 함수로 분류)
폼 태그 다루기-체크박스, 라디오버튼, 콤보박스
체크 박스 가져오기
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h3>멋쟁이사자처럼 11기</h3>
<input type="checkbox" id="front" name="role" value="프론트엔드"> 프론트엔드
<input type="checkbox" id="backend" name="role" value="백엔드"> 백엔드
<input type="checkbox" id="planning" name="role" value="기획"> 기획
<input type="checkbox" id="operation" name="role" value="운영"> 운영
<input type="checkbox" id="education" name="role" value="교육"> 교육
<button onclick="getCheckedValues()">선택된 값 가져오기</button>
<script>
function getCheckedValues(){
let checkboxes=document.querySelectorAll('input[type="checkbox"]');
let checkValues=[];
checkboxes.forEach(checkbox =>{
if(checkbox.checked){
checkValues.push(checkbox.value);}
});
console.log('체크된 값: ', checkValues);
}
</script>
</body>
</html>

라디오 버튼 가져오기
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h3>멋쟁이사자처럼 11기</h3>
<input type="radio" id="front" name="role" value="프론트엔드"> 프론트엔드
<input type="radio" id="backend" name="role" value="백엔드"> 백엔드
<input type="radio" id="planning" name="role" value="기획"> 기획
<input type="radio" id="operation" name="role" value="운영"> 운영
<input type="radio" id="education" name="role" value="교육"> 교육
<button onclick="getCheckedValues()">선택된 값 가져오기</button>
<script>
function getCheckedValues(){
let radioButtons
=document.querySelectorAll('input[type="radio"]');
let checkValue;
radioButtons.forEach(radioButton =>{
if(radioButton.checked){
checkValue=radioButton.value;}
});
console.log('체크된 값: ', checkValue);
}
</script>
</body>
</html>

콤보박스 가져오기
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<select name="language" onchange="handleOnChange(this)">
<option value="korean">한국어</option>
<option value="english">영어</option>
<option value="chinese">중국어</option>
<option value="spanish">스페인어</option>
</select>
<div id='result'></div>
<script>
function handleOnChange(e) {
// 선택된 데이터 가져오기
const value = e.value;
// 데이터 출력
document.getElementById('result').innerText
= value;
}
</script>
</body>
</html>
