1. Dom 내부 이벤트
- 태그 내부에 이벤트 요소를 직접 삽입
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>이벤트</h1>
<hr>
<button onclick="m1()">클릭</button>
<div onclick="m2()">클릭2</div>
<script>
function m1() {
// window 객체는 생략 가능
window.alert("m1 호출됨");
}
function m2() {
// window 객체는 생략 가능
window.alert("m2 호출됨");
}
</script>
</body>
</html>


2. EventListener
- script 내부에 이벤트를 호출할 객체를 지정한 후 이벤트 리스너를 추가
- 리스너 내부에는 발동시킬 이벤트명, 이벤트 발동 시 처리 (Lambda Statement)를 추가
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>이벤트 리스너</h1>
<hr>
<button id="btn1">클릭</button>
<script>
let btn1 = document.querySelector("#btn1");
// Lambda 사용
btn1.addEventListener("click", (e) => {
console.log(e);
alert("btn1 호출됨");
});
</script>
</body>
</html>

3. 이벤트 종류

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>이벤트 예제</title>
</head>
<body>
<h1>이벤트 종류</h1>
<hr>
<!-- click -->
<button id="btn1">클릭</button>
<!-- dblclick -->
<button id="btn2">더블 클릭</button>
<!-- keyup -->
<input type="text" id="textInput" placeholder="키보드 입력해 보세요">
<!-- change -->
<select id="selectBox">
<option value="">선택하세요</option>
<option value="apple">🍎 사과</option>
<option value="banana">🍌 바나나</option>
<option value="grape">🍇 포도</option>
</select>
<script>
// click
let btn1 = document.querySelector("#btn1");
btn1.addEventListener("click", (e) => {
console.log("click 이벤트:", e);
alert("btn1 클릭됨");
});
// dblclick
let btn2 = document.querySelector("#btn2");
btn2.addEventListener("dblclick", () => {
alert("btn2 더블 클릭됨");
});
// keyup
let value = "";
let input = document.querySelector("#textInput");
input.addEventListener("keyup", (e) => {
console.log("입력된 키:", e.key);
value += e.key;
if (value.length > 4) alert("글자수 5");
});
// change
let select = document.querySelector("#selectBox");
select.addEventListener("change", (e) => {
alert("선택한 값: " + e.target.value);
console.log(e);
});
</script>
</body>
</html>
- click : 해당 dom 클릭 시 발생

- dblclick : 해당 dom 더블 클릭 시 발생

- keyup : 키가 올라올 때 (키를 눌렀다 땔 때) 발생

- change : 값이 변경되고 cursor가 옮겨갈 때 (tab) 발생


4. 비밀번호 확인
- 3중 체크 필요
- 비밀번호 값 비교 후 동일한지 확인
- 비밀번호와 비밀번호 체크 칸의 값이 현재도 동일한지 확인
- 폼 이동 시 (submit 시) 한번 더 체크
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.hidden-box {
display: none;
}
.red-text {
font-size: 10px;
color: red;
}
</style>
</head>
<body>
<h1>폼 이벤트</h1>
<hr>
<form action="/join" onsubmit="return valid()">
<input type="text" id="password"><br>
<input type="text" id="password-check"><br>
<div id="pw-same" class="pw-box hidden-box red-text">패스워드가 동일합니다</div>
<div id="pw-not-same" class="pw-box hidden-box red-text">패스워드가 동일하지 않습니다</div>
<button type="submit">회원가입</button>
</form>
<script>
let pw = document.querySelector("#password");
let pwCheck = document.querySelector("#password-check");
function valid() {
if (pw.value == pwCheck) {
return true;
} else {
return false;
}
}
pw.addEventListener("keyup", (e) => {
if (pw.value == pwCheck.value) {
pw.readOnly = true;
document.querySelector("#pw-same").classList.remove("hidden-box");
document.querySelector("#pw-not-same").classList.add("hidden-box");
} else {
pw.readOnly = false;
document.querySelector("#pw-same").classList.add("hidden-box");
document.querySelector("#pw-not-same").classList.remove("hidden-box");
}
});
pwCheck.addEventListener("keyup", (e) => {
if (pw.value == pwCheck.value) {
pw.readOnly = true;
document.querySelector("#pw-same").classList.remove("hidden-box");
document.querySelector("#pw-not-same").classList.add("hidden-box");
} else {
pw.readOnly = false;
document.querySelector("#pw-same").classList.add("hidden-box");
document.querySelector("#pw-not-same").classList.remove("hidden-box");
}
});
</script>
</body>
</html>


5. 박스 숨기기
- 숨기기
- display = none
- 박스 칸을 아예 안보이게 함
- visibility = hidden
- 박스 공간은 놔두고, 객체만 보이지 않음
- innerHTML = “”;
- 박스 내의 HTML을 공백으로 비움 = 요소 전부 삭제
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.box {
border: 1px solid black;
padding: 10px;
}
</style>
</head>
<body>
<h1>숨기기</h1>
<button onclick="hideDisplay()">display로 숨기기</button>
<button onclick="hideVisible()">visible로 숨기기</button>
<button onclick="empty()">박스 내부 날리기</button>
<div class="box" id="outerBox">
<div class="box" id="innerBox1">
내부박스1
</div>
<div class="box" id="innerBox2">
내부박스2
</div>
</div>
<script>
function hideDisplay() {
let el = document.querySelector("#innerBox1");
el.style.display = "none";
}
function hideVisible() {
let el = document.querySelector("#innerBox2");
el.style.visibility = "hidden";
}
function empty() {
let el = document.querySelector("#outerBox");
// 1. 내부 내용 다 비우기
// el.innerHTML = "";
console.log(el.children);
let cs = el.children;
Array.from(cs).forEach(element => {
element.style.display = "none";
});
}
</script>
</body>
</html>

- display로 숨기기

- visible로 숨기기

- 박스 내부 날리기

6. 박스 나타내기
- 숨기기와 반대
- display : block
- visibility = visible
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.box {
border: 1px solid black;
padding: 10px;
}
#innerBox1 {
display: none;
}
#innerBox2 {
visibility: hidden;
}
</style>
</head>
<body>
<h1>나타내기</h1>
<button onclick="showByDisplay()">display로 나타내기</button>
<button onclick="showByVisible()">visible로 나타내기</button>
<div class="box" id="outerBox">
<div class="box" id="innerBox1">
내부박스1
</div>
<div class="box" id="innerBox2">
내부박스2
</div>
</div>
<script>
function showByDisplay() {
let el = document.querySelector("#innerBox1");
el.style.display = "block";
}
function showByVisible() {
let el = document.querySelector("#innerBox2");
el.style.visibility = "visible";
}
</script>
</body>
</html>
- display로 나타내기

- visible로 나타내기

7. 박스 추가하기
- createElement로 div 생성 후 setAttribute
- id를 추가할 수는 있으나, id가 중복되면 id로 한 개만을 제어할 수 없게 됨
- 내부 이벤트를 통한 제어가 필요
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.box {
border: 1px solid black;
padding: 10px;
}
</style>
</head>
<body>
<h1>추가하기</h1>
<button onclick="addAppend()">append로 추가하기</button>
<button onclick="addPrepend()">prepend로 추가하기</button>
<button onclick="addBefore()">before로 추가하기</button>
<button onclick="addAfter()">after로 추가하기</button>
<div class="box" id="outerBox">
</div>
<script>
function del(e) {
console.log(e.target);
e.target.style.display = "none";
}
function addAppend() {
let newEl = document.createElement("div");
newEl.setAttribute("class", "box");
newEl.setAttribute("onclick", "del(event)");
newEl.innerHTML = "내부박스1";
let el = document.querySelector("#outerBox");
el.append(newEl);
}
function addPrepend() {
let newEl = document.createElement("div");
newEl.setAttribute("class", "box");
newEl.setAttribute("id", "innerBox2");
newEl.innerHTML = "내부박스2";
let el = document.querySelector("#outerBox");
el.prepend(newEl);
}
function addBefore() {
let newEl = document.createElement("div");
newEl.setAttribute("class", "box");
newEl.setAttribute("id", "innerBox3");
newEl.innerHTML = "내부박스3";
let el = document.querySelector("#outerBox");
el.before(newEl);
}
function addAfter() {
let newEl = document.createElement("div");
newEl.setAttribute("class", "box");
newEl.setAttribute("id", "innerBox4");
newEl.innerHTML = "내부박스4";
let el = document.querySelector("#outerBox");
el.after(newEl);
}
</script>
</body>
</html>

8. 박스 삭제하기
- 내부 이벤트 vs id를 참조한 Listener의 차이
- 내부 이벤트 : 이벤트를 발생시킨 dom 자신을 제어해야 할 때 사용
- Listener : 이벤트를 통해 제어해야 할 dom이 자신이 아닌 경우 사용
- id를 통해 추적
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.box {
border: 1px solid black;
padding: 10px;
}
</style>
</head>
<body>
<h1>삭제하기</h1>
<button onclick="del(event)">remove로 삭제하기</button>
<div class="box" id="outerBox">
<div class="box" id="innerBox1">
내부박스1
</div>
</div>
<script>
function del(e) {
console.log(e.target);
let el = document.querySelector("#innerBox1");
el.remove();
}
</script>
</body>
</html>

9. 반복문 활용
- id의 동적 할당 : id의 번호만 추적해서 해당 박스를 삭제할 수 있음
- 데이터를 받아야 할 경우 보통 primary key로 받게 됨 : index
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.box {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
border: 1px solid black;
padding: 10px;
}
.card {
border: 1px solid lightgray;
box-shadow: 0 4px 4px 0 grey;
padding: 10px;
margin: 5px;
border-radius: 5px;
}
</style>
</head>
<body>
<h1>반복문으로 리스트 만들기</h1>
<button onclick="render()">render</button>
<div class="box" id="outerBox">
</div>
<script>
let id = 1;
function render() {
let el = document.querySelector("#outerBox");
// for (let i = 1; i < 5; i++) {
el.append(makeCard(id));
id++;
// }
}
function makeCard(id) {
let card = document.createElement("div");
card.setAttribute("class", "card");
card.setAttribute("id", "card-" + id);
card.innerHTML = `
<h3>제목${id} 입니다</h3>
<p>내용${id} 입니다</p>
<button onclick="del(${id})">삭제</button>
`;
return card;
}
function del(id) {
let el = document.querySelector("#card-" + id);
el.remove();
}
</script>
</body>
</html>

Share article