#Default 상황 :
- 아래와 같이, 기존의 ul태그 li태그 항목들이 있다.
- 각 li 태그에 클릭을 하게 될 경우, .done 클래스의 css 스타일 add되어, 항목이 완료됐다는 이벤트 핸들러 적용
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>이벤트 위임</title>
<style>
.done {
text-decoration: line-through;
opacity: 0.5;
}
</style>
</head>
<body>
<h3 id="title">오늘 할 일</h3>
<ul id="list">
<li class="item">자바스크립트 공부 </li>
<li class="item">유투브 시청 </li>
<li class="item">저녁 약속 </li>
<li class="item">독서 </li>
<li class="item">일기 쓰기 </li>
</ul>
<script>
const list = document.querySelector('#list');
for (let i of list.children) {
i.addEventListener('click', function (event) {
event.target.classList.add('done');
});
}
const li = document.createElement('LI');
li.textContent = "자살하기";
document.querySelector('#list').append(li);
</script>
</body>
</html>
● 문제 상황 :
- JavaScript 코드에서 li 요소 노드 - "자살하기"를 한개 더 추가하게 되면, "자살하기" li 요소노드는 해당 스타일 시트 적용이 되지 않는다.
- 이유. 코드 순서상 기존의 li 요소노드들만("자살하기" 제외) addEventListener()만 적용되어있다.
● ★해결 방법 : ★요소노드.classList의 프로퍼티 메소드 contains('class속성값')메소드
①. 그의 상위 노드인 <ul> 노드에 addEventList()로 이벤트 핸들러 적용
=> li를 눌러도 적용되고, li가 아닌 ul을 눌러도 적용됨
②.if조건절 + contains()메소드를 이용해, li가 있는 부분만 시트 적용되도록 한다
● 정답 :
/*
기존 addEventListener() 이벤트 핸들러 적용
for (let i of list.children) {
i.addEventListener('click', function (event) {
event.target.classList.add('done');
});
}
*/
list.addEventListener('click',function(event){
if(event.target.classList.contains('item')){
event.target.classList.add('done');
}
});
const li = document.createElement('LI');
li.classList.add('item');//item 클래스 추가 깜빡함
li.textContent = "자살하기";
document.querySelector('#list').append(li);
최종적으로, 이 방법이 event 위임 과정의 정석이므로, 암기할정도로 숙지하여, 자주 사용하셈
◎ 연습문제 :
실습 설명
지용이는 지난 번에 이벤트 객체와 반복문을 활용해서 할 일을 완료하는 기능을 만들었습니다.
잠깐동안 자신이 만든 코드를 보며 흐뭇해 하긴 했지만 금세 몇 가지 문제를 발견하게 되었습니다.
자바스크립트로 새롭게 할 일을 추가하게 되면 이벤트 핸들러를 새롭게 등록해 주어야 한다는 문제를 발견했고, 이벤트 핸들러를 불필요하게 많이 등록하면 프로그램의 성능에도 부정적인 영향을 미친다는 사실도 알게 되었습니다.
이번에도 지용이는 이를 어떻게 해결할지 막막한데요.
지용이를 위해 아래 조건에 맞는 코드를 작성해 주세요.
- 1. 이벤트 위임을 활용할 수 있도록 이벤트 핸들러 updateToDo 함수를 완성해 주세요.
- updateToDo는 이벤트가 발생한 대상이 item이라는 클래스 속성 값을 가지고 있을 때 동작해야 합니다.
- 2. 이벤트 핸들러를 li 태그 각각에 등록하는 것이 아니라 하나의 태그에만 등록해 주세요.
코드를 잘 작성했다면, 아래 내용처럼 페이지가 동작해야 합니다.
- 1. 첫 번째 두 번째 할 일 뿐만아니라 자바스크립트로 추가한 네 번째 할 일을 클릭할 때도 'done'이라는 class 속성값이 toggle되면서 스타일 변해야 합니다.
- 2.★ 세 번째 할 일은 클릭을 해도 아무런 변화가 없어야 합니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>오늘 할 일</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="main">
<h2 class="title">오늘 할 일</h2>
<ul id="to-do-list">
<li class="item">자바스크립트 공부하기</li>
<li class="item">고양이 화장실 청소하기</li>
<li class="item">고양이 장난감 쇼핑하기</li>
</ul>
</div>
<script src="index.js"></script>
</body>
</html>
body {
margin: 0;
padding: 0;
display: flex;
align-items: center;
justify-content: center;
}
.main {
width: 350px;
margin: 40px;
padding: 30px 0;
background-color: #FCFCFC;
box-shadow: -5px -5px 20px #DFDFDF, 5px 5px 20px #BABECC;
border-radius: 8px;
text-align: center;
}
.title {
margin: 15px auto;
font-size: 30px;
font-weight: 600;
color: #9600FF;
}
#to-do-list {
width: 280px;
margin: 0 auto 15px;
padding: 0;
list-style: none;
}
#to-do-list li {
display: flex;
align-items: center;
justify-content: center;
width: 90%;
height: 40px;
margin: 8px auto 15px;
border-bottom: 1px solid #9600FF;
cursor: pointer;
}
.done {
opacity: 0.5;
text-decoration: line-through;
}
● 풀이 과정 :
①. 클릭시, "done" class 가 추가 되도록 하는 updateToDo() 메소드 작성 (+ if 조건절 + 요소노드.classList.contains('태그내용') 적용)
②. li 태그들의 상위 요소노드에 이벤트 핸들러 적용
③. 새로운 <li> 요소노드 "가계부 정리하기" 추가하기
④. 세번째는 적용 배제 => removeEventListener();
● 정답 :
const toDoList = document.querySelector('#to-do-list');
// 1. updateToDo 함수를 완성해 주세요
function updateToDo(event) {
if(event.target.classList.contains('item'))
{
event.target.classList.add('done');
}
}
// 2. 각 li 태그가 아니라 하나의 태그에만 이벤트 핸들러를 등록해 주세요
toDoList.addEventListener('click',updateToDo);
// 테스트 코드
const newToDo = document.createElement('li');
newToDo.textContent = '가계부 정리하기';
newToDo.classList.add('item');
toDoList.append(newToDo);
//세번째는 클릭해도 적용안되도록 배제하기 => removeEventListener()
toDoList.children[2].addEventListener('click', function(e) {e.stopPropagation()});
'CodeIt_Sprint > JavaScript_중급' 카테고리의 다른 글
(8)JavaScript중급_3_5_event 객체의 프로퍼티 메소드 : preventDefault() (0) | 2024.11.13 |
---|---|
(6)JavaScript중급_3_3_이벤트 버블링과 이벤트흐름(DOM이벤트객체 경로과정) (1) | 2024.11.13 |
(5)JavaScript중급_3_2_이벤트객체 (0) | 2024.11.13 |
(4)JavaScript중급_3_1_이벤트핸들러 등록 (0) | 2024.11.13 |
(2)JavaScript중급_2_DOM객체_개념부분(이론요약)[작성중..] (0) | 2024.11.11 |