12. 클릭하고 반응하기 (이벤트 처리)/12.3 이벤트 위임

12.3.2 동적 요소에 이벤트 걸기 - 새로 온 친구들도 함께하는 따뜻한 시스템

thejavascript4kids 2025. 7. 17. 03:03

📘 12.3.2 동적 요소에 이벤트 걸기 - 새로 온 친구들도 함께하는 따뜻한 시스템

안녕하세요, 여러분. 지난 시간에 이벤트 위임의 기본 개념을 배우면서, 부모 요소 하나로 여러 자식 요소의 이벤트를 관리하는 방법을 익혔죠? 이제는 이 지식을 바탕으로 더 흥미로운 상황에 도전해보려고 합니다. 바로 JavaScript로 나중에 만들어지는 동적 요소들에도 이벤트를 적용하는 방법이에요. 마치 새로 이사온 이웃에게도 자연스럽게 동네의 따뜻함이 전해지는 것처럼 말이에요.

🧠 새로운 단어들과 친해지기

동적으로 변화하는 웹페이지를 만드는 데 필요한 소중한 단어들을 차근차근 알아보겠습니다.

단어 마음을 담은 설명
동적 요소 JavaScript로 나중에 만들어서 페이지에 추가하는 HTML 요소들이에요. 마치 새로 싹튼 잎사귀처럼요.
동적 이벤트 나중에 추가되는 요소에도 저절로 적용되는 이벤트 처리 방식이에요.
DOM 업데이트 웹페이지에 새로운 요소를 추가하거나 제거하는 작업이에요.
이벤트 연결 요소에 이벤트 리스너를 연결하는 작업을 말해요.

동적이라는 말은 "움직이는, 변화하는"이라는 뜻으로, 페이지가 로딩된 후에도 계속 변화할 수 있다는 의미예요.

✨ 동적 요소와 이벤트의 핵심 개념

현대 웹페이지는 정적이지 않습니다. 사용자가 버튼을 클릭하면 새로운 카드가 나타나고, 폼을 작성하면 목록에 새 항목이 추가되며, 게임에서는 계속해서 새로운 객체들이 생성돼요. 이런 동적인 변화가 바로 웹을 흥미롭게 만드는 요소예요.

하지만 여기서 중요한 문제가 하나 있어요. JavaScript로 새로 만든 요소들은 기존에 걸어둔 이벤트 리스너가 적용되지 않는다는 점이에요. 마치 새로 이사온 사람이 동네 소식을 받지 못하는 것과 같은 상황이죠.

예를 들어, 페이지 로딩 시에 있던 버튼들에는 클릭 이벤트를 걸어뒀지만, 나중에 createElement로 만든 버튼은 클릭해도 아무 반응이 없어요. 이는 이벤트 리스너가 걸려있을 당시에는 그 버튼이 존재하지 않았기 때문이에요.

다행히 이 문제는 이벤트 위임으로 아름답게 해결할 수 있어요. 부모 요소에 이벤트를 걸어놓으면, 자식이 언제 추가되든 상관없이 저절로 이벤트가 적용돼요. 이는 현대 웹 개발의 소중한 기법 중 하나예요.

마음을 담은 비유: 마을의 우체국 이야기

동적 이벤트를 좀 더 친근하게 이해하기 위해 '마을의 우체국' 이야기를 해볼게요.

어떤 작은 마을에는 참으로 따뜻한 우체국 시스템이 있어요. 각 집마다 개별 우편함이 있지만, 모든 우편물은 먼저 마을 중앙의 우체국으로 도착해요. 그러면 우체국에서 "101번지로 온 편지", "205번지로 온 택배"를 확인해서 각 집에 배달해주죠.

이 시스템의 아름다운 점은 새로운 집이 지어져도 문제없다는 것이에요. 301번지에 새 집이 지어졌다고 해서 새로운 우편 시스템을 만들 필요가 없어요. 기존의 중앙 우체국이 자연스럽게 301번지 우편물도 처리해줘요.

웹페이지의 동적 이벤트도 정확히 이와 같습니다. 부모 요소가 중앙 우체국 역할을 하고, 새로 추가되는 자식 요소들은 새로 지어진 집이에요. 자식에서 이벤트가 발생하면 부모가 이를 받아서 "어떤 자식에서 무슨 이벤트가 발생했는지" 파악하고 따뜻한 처리를 해주는 것이죠.

🎯 동적 이벤트를 사용하는 이유

그렇다면 개발자들은 왜 동적으로 요소를 만들고 이벤트를 적용할까요? 몇 가지 소중한 이유들이 있어요.

첫 번째로 사용자가 더 편안하게 느끼도록 하기 위해서예요. 사용자가 "새 항목 추가" 버튼을 클릭하면 즉시 새로운 항목이 나타나고, 그 항목도 기존 항목들과 똑같이 클릭하고 조작할 수 있어야 해요. 이런 부드러운 상호작용이 현대 웹의 기본 요구사항이에요.

두 번째로 메모리를 효율적으로 사용하기 위해서예요. 페이지 로딩 시에 모든 가능한 요소를 미리 만들어두는 것보다는, 필요할 때만 만들어서 추가하는 것이 훨씬 효율적이에요. 하지만 이렇게 나중에 추가된 요소들도 기존 요소들과 동일한 기능을 가져야 하죠.

세 번째로 코드를 더 쉽게 돌보기 위해서예요. 각 새로운 요소마다 개별적으로 이벤트를 걸어주는 대신, 이벤트 위임을 사용하면 코드가 훨씬 간단하고 관리하기 쉬워져요. 나중에 기능을 수정할 때도 한 곳만 바꾸면 모든 요소에 적용돼요.

마지막으로 동적 콘텐츠를 지원하기 위해서예요. 게시판, 쇼핑몰, 게임 등 사용자의 행동에 따라 콘텐츠가 계속 변화하는 웹페이지에서는 동적 이벤트 처리가 필수적이에요.

⚙️ 기본 사용법 살펴보기

동적 요소에 이벤트를 적용하는 방법은 이벤트 위임의 활용이에요. 문법 자체는 복잡하지 않지만, 타이밍이 중요해요.

// 잘못된 방법 - 나중에 추가된 요소는 이벤트가 없어요
document.querySelectorAll(".button").forEach(function(btn) {
    btn.addEventListener("click", function() {
        console.log("클릭됨");
    });
});

// 올바른 방법 - 이벤트 위임 사용
부모요소.addEventListener("click", function(event) {
    if (event.target.classList.contains("button")) {
        console.log("클릭됨"); // 언제 추가된 버튼이든 작동
    }
});

실제 예시:

// 컨테이너에 이벤트 위임 설정
let container = document.getElementById("buttonContainer");
container.addEventListener("click", function(event) {
    if (event.target.tagName === "BUTTON") {
        console.log("버튼 클릭:", event.target.textContent);
    }
});

// 나중에 새 버튼 추가
let newButton = document.createElement("button");
newButton.textContent = "새 버튼";
container.appendChild(newButton); // 자동으로 이벤트 적용됨

핵심 포인트:

가장 중요한 것은 순서예요. 이벤트 위임은 요소를 추가하기 전에 미리 설정해놓아야 해요. 그리고 새 요소를 만들 때는 부모가 인식할 수 있는 적절한 태그명이나 클래스명을 부여해야 해요.

🧪 직접 해보며 배우기

이제 실제 예시를 통해 동적 요소에 이벤트를 적용하는 방법을 차근차근 살펴볼게요.

🔹 첫 번째 예시: 동적 버튼 생성과 이벤트 적용

첫 번째 예시에서는 버튼을 클릭할 때마다 새로운 버튼이 추가되고, 그 새 버튼도 클릭 기능을 갖는 시스템을 만들어볼게요.

// 버튼들을 품을 컨테이너와 추가 버튼을 찾아와요
let buttonContainer = document.getElementById("buttonContainer");
let addButton = document.getElementById("addNewButton");

// 컨테이너에 이벤트 위임을 설정해요 (미리 설정하는 것이 중요해요!)
buttonContainer.addEventListener("click", function(event) {
    // 클릭된 요소가 동적 버튼인지 확인해요
    if (event.target.classList.contains("dynamic-button")) {
        console.log("동적 버튼 클릭됨:", event.target.textContent);
        // 클릭된 버튼의 색상을 부드럽게 변경해요
        event.target.style.backgroundColor = "lightgreen";
        event.target.textContent = "클릭됨!";
    }
});

// 새 버튼을 추가하는 기능을 만들어요
addButton.addEventListener("click", function() {
    let newButton = document.createElement("button");
    newButton.textContent = "새 버튼";
    newButton.classList.add("dynamic-button"); // 중요: 클래스 추가해요
    buttonContainer.appendChild(newButton);
    console.log("새 버튼이 추가되었어요!");
});

이 과정을 차근차근 살펴보면, 먼저 필요한 요소들을 찾아와요. 그다음 가장 중요한 단계인 이벤트 위임을 컨테이너에 미리 설정해요. 이때 아직 동적 버튼은 존재하지 않지만, 나중에 추가될 것을 대비해서 미리 준비하는 것이죠. 마지막으로 새 버튼을 추가하는 기능을 구현하면, 추가된 버튼들이 저절로 클릭 기능을 가지게 돼요.

🔹 두 번째 예시: 동적 할 일 목록 만들기

두 번째 예시에서는 사용자가 할 일을 추가할 때마다 새로운 목록 항목이 생성되고, 그 항목들을 클릭해서 완료 처리할 수 있는 시스템을 만들어볼게요.

// 할 일 목록과 입력 관련 요소들을 찾아와요
let todoList = document.getElementById("todoList");
let addTodoButton = document.getElementById("addTodoButton");
let todoInput = document.getElementById("todoInput");

// 할 일 목록에 이벤트 위임을 설정해요
todoList.addEventListener("click", function(event) {
    // 클릭된 요소가 할 일 항목인지 확인해요
    if (event.target.classList.contains("todo-item")) {
        console.log("할 일 항목 클릭:", event.target.textContent);

        // 완료 상태를 부드럽게 바꿔줘요 (완료 ↔ 미완료)
        if (event.target.classList.contains("completed")) {
            event.target.classList.remove("completed");
            event.target.style.textDecoration = "none";
        } else {
            event.target.classList.add("completed");
            event.target.style.textDecoration = "line-through";
        }
    }
});

// 새 할 일을 추가하는 기능을 만들어요
addTodoButton.addEventListener("click", function() {
    let todoText = todoInput.value.trim();
    if (todoText === "") {
        alert("할 일을 입력해주세요!");
        return;
    }

    let newTodoItem = document.createElement("li");
    newTodoItem.textContent = todoText;
    newTodoItem.classList.add("todo-item"); // 중요: 클래스 추가해요
    todoList.appendChild(newTodoItem);

    todoInput.value = "";
    console.log("새 할 일이 추가되었어요:", todoText);
});

이 예시를 차근차근 들여다보면, 먼저 할 일 목록과 입력 요소들을 준비해요. 그다음 목록 컨테이너에 이벤트 위임을 설정해서 클릭 시 완료 상태를 바꿔주는 기능을 구현해요. 마지막으로 새 할 일을 추가하는 기능을 만들면, 추가된 모든 항목이 저절로 완료 체크 기능을 갖게 돼요. 입력값 검증과 입력창 초기화도 함께 처리해서 사용자가 더 편하게 느낄 수 있도록 했어요.

🔹 세 번째 예시: 동적 카드 선택 시스템

세 번째 예시에서는 카드를 추가할 때마다 새로운 카드가 생성되고, 그 카드들 중에서 하나씩 선택할 수 있는 시스템을 만들어볼게요.

// 카드 영역과 추가 버튼을 찾아와요
let cardArea = document.getElementById("cardArea");
let createCardButton = document.getElementById("createCardButton");

// 카드 영역에 이벤트 위임을 설정해요
cardArea.addEventListener("click", function(event) {
    // 클릭된 요소가 카드인지 확인해요
    if (event.target.classList.contains("card")) {
        console.log("카드가 선택되었어요:", event.target.textContent);

        // 먼저 모든 카드의 선택 상태를 부드럽게 해제해요
        let allCards = cardArea.querySelectorAll(".card");
        for (let i = 0; i < allCards.length; i++) {
            allCards[i].classList.remove("selected");
            allCards[i].style.border = "2px solid gray";
        }

        // 클릭된 카드만 선택 상태로 만들어요
        event.target.classList.add("selected");
        event.target.style.border = "2px solid blue";
    }
});

// 새 카드를 생성하는 기능을 만들어요
createCardButton.addEventListener("click", function() {
    let cardNumber = cardArea.children.length + 1;

    let newCard = document.createElement("div");
    newCard.textContent = "카드 " + cardNumber;
    newCard.classList.add("card"); // 중요: 클래스 추가해요
    newCard.style.padding = "20px";
    newCard.style.margin = "10px";
    newCard.style.border = "2px solid gray";
    newCard.style.cursor = "pointer";

    cardArea.appendChild(newCard);
    console.log("새 카드가 생성되었어요:", newCard.textContent);
});

이 예시에서는 카드 선택 시스템을 구현하는 방법을 배울 수 있어요. 먼저 카드 영역에 이벤트 위임을 설정하고, 카드 클릭 시 기존 선택을 모두 해제한 후 클릭된 카드만 선택하는 로직을 구현해요. 새 카드 생성 기능에서는 카드 번호를 자동으로 부여하고 기본 스타일을 설정해서, 생성된 모든 카드가 일관된 모습과 기능을 갖도록 했어요.

🔄 동적 이벤트 적용 과정 정리하기

지금까지 학습한 동적 요소에 이벤트를 적용하는 단계를 자연스럽게 정리해볼게요.

첫 번째 단계부모 컨테이너 준비하기예요. 동적으로 추가될 요소들을 담을 적절한 부모 요소를 선택하고, 그 요소가 HTML에 이미 존재하는지 확인해야 해요.

두 번째는 사전 이벤트 위임 설정하기 단계예요. 아직 자식 요소들이 존재하지 않더라도, 미리 부모 요소에 이벤트 위임을 설정해놓아요. 이는 나중에 추가될 요소들을 위한 준비 과정이에요.

세 번째는 동적 요소 생성하기 단계예요. createElement로 새로운 요소를 만들고, 부모가 인식할 수 있도록 적절한 태그명, 클래스명, 또는 속성을 부여해요.

네 번째는 DOM에 추가하기 단계예요. appendChildinsertBefore 등을 사용해서 새 요소를 부모 컨테이너에 추가해요.

마지막 단계는 자동 이벤트 활성화 확인하기예요. 요소가 DOM에 추가되는 순간부터 이벤트 위임에 의해 저절로 이벤트가 적용되는 것을 확인해요.

🧚‍♀️ 이야기로 다시 배우기: 따뜻한 학교의 선생님

지금까지 배운 내용을 하나의 이야기로 다시 정리해볼까요?

작은 시골 학교에 오신 것을 환영해요. 이 학교에는 30명의 학생이 있는 따뜻한 교실이 있어요. 학기 중에는 새로운 학생들이 전학을 오기도 해요.

처음에는 각 학생의 책상마다 개별 벨을 설치하고, 각각의 벨에 개별 선생님을 배치할 수도 있었지만, 학교는 더 따뜻한 방법을 선택했어요. "우리 교실 학생증을 가진 모든 아이의 도움 요청에 응답한다"는 하나의 규칙을 교실에 설정한 것이에요.

이제 새로운 학생이 전학을 와도 문제없어요. 새 학생이 학생증만 받으면, 선생님이 즉시 그 아이를 우리 교실의 한 명으로 인식하고 똑같은 관심과 도움을 주세요. 개별 벨을 새로 설치하거나, 교실 시스템을 바꿀 필요가 전혀 없어요.

심지어 학번이 몇 번이든, 언제 전학 왔든 상관없이 모든 학생에게 동일한 따뜻함이 적용돼요. 1번 학생이든 1000번 학생이든, 어제 전학 온 학생이든 1년 전에 입학한 학생이든 모두 똑같은 사랑을 받아요.

이것이 바로 동적 이벤트의 원리예요. 부모 요소라는 따뜻한 선생님에 하나의 규칙(이벤트 위임)을 설정해놓으면, 나중에 추가되는 모든 자식 요소들이 저절로 그 따뜻함의 혜택을 받게 되는 것이죠!

🧠 자주 하는 실수와 주의할 점

동적 요소에 이벤트를 적용할 때 주의해야 할 몇 가지 실수들을 미리 알아두면 더 안전하게 사용할 수 있어요.

❌ 실수 1: 기존 요소에만 이벤트를 걸고 동적 요소는 무시하기

// 잘못된 방법 - 나중에 추가된 요소는 이벤트가 없어요
document.querySelectorAll(".item").forEach(function(item) {
    item.addEventListener("click", function() {
        console.log("아이템 클릭됨"); // 새로 추가된 아이템은 반응하지 않아요
    });
});

// 새 아이템 추가 (하지만 이벤트가 없어서 클릭해도 반응 없어요)
let newItem = document.createElement("div");
newItem.className = "item";
newItem.textContent = "새 아이템";
container.appendChild(newItem);

// 올바른 방법 - 이벤트 위임 사용
container.addEventListener("click", function(event) {
    if (event.target.classList.contains("item")) {
        console.log("아이템 클릭됨"); // 새 아이템도 작동해요
    }
});

이런 실수가 발생하는 이유는 querySelectorAll이 호출되는 시점에 존재하던 요소들에만 이벤트가 걸리기 때문이에요. 나중에 추가된 요소는 그 시점에 존재하지 않았으므로 이벤트가 적용되지 않아요.

❌ 실수 2: 새 요소를 추가할 때마다 개별적으로 이벤트 걸어주기

// 비효율적인 방법 - 매번 개별 등록
function addNewItem(text) {
    let newItem = document.createElement("div");
    newItem.textContent = text;
    container.appendChild(newItem);

    // 매번 새로 이벤트 걸어주기 (비효율적이에요!)
    newItem.addEventListener("click", function() {
        console.log("클릭됨");
    });
}

// 효율적인 방법 - 미리 위임 설정
container.addEventListener("click", function(event) {
    if (event.target.tagName === "DIV") {
        console.log("클릭됨");
    }
});

function addNewItem(text) {
    let newItem = document.createElement("div");
    newItem.textContent = text;
    container.appendChild(newItem); // 자동으로 이벤트 적용돼요
}

매번 개별적으로 이벤트를 걸어주면 메모리 사용량이 늘어나고, 코드도 복잡해져요. 또한 나중에 이벤트 로직을 수정할 때 모든 곳을 다 바꿔야 하는 문제도 생겨요.

❌ 실수 3: 이벤트 위임 설정 전에 요소를 추가하기

// 문제가 될 수 있는 순서
let newItem = document.createElement("div");
newItem.className = "item";
container.appendChild(newItem); // 이벤트 위임 설정 전에 추가

// 나중에 이벤트 위임 설정 (이미 추가된 요소도 적용돼요)
container.addEventListener("click", function(event) {
    if (event.target.classList.contains("item")) {
        console.log("클릭됨"); // 다행히 작동해요
    }
});

다행히 이벤트 위임은 이미 존재하는 요소에도 적용되므로 큰 문제는 없지만, 코드의 의도를 명확히 하기 위해서는 이벤트 위임을 먼저 설정하는 것이 좋아요.

✏️ 연습문제로 개념 다지기

이제 배운 내용을 연습문제를 통해 확실히 익혀볼게요.

작은 마음을 담아, 이번 연습문제들은 아이들이 즐거워할 만한 상황들로 준비해보았어요. 마치 친구들과 함께 놀이를 하듯 가벼운 마음으로 접근해주세요.

Ex1) 버튼 추가하면 그 버튼이 "나는 새로운 버튼이야!"라고 말하게 만들어보자

// 컨테이너와 추가 버튼을 찾아서 변수에 담아요
let container = document.getElementById("container");
let addBtn = document.getElementById("addBtn");

// 이벤트 위임을 설정해요
container.addEventListener("click", function(event) {
    if (event.target.tagName === "BUTTON") {
        alert("나는 새로운 버튼이야!");
    }
});

// 새 버튼을 추가하는 기능을 만들어요
addBtn.addEventListener("click", function() {
    let newBtn = document.createElement("button");
    newBtn.textContent = "새 버튼";
    container.appendChild(newBtn);
});

이 연습을 통해 동적 버튼 생성과 이벤트 적용의 기본 원리를 익힐 수 있어요.

Ex2) 할 일 추가하면 그 할 일을 클릭했을 때 "완료했어요!" 표시(줄 긋기)가 되는 시스템 만들어보자

// 필요한 요소들을 찾아서 변수에 담아요
let todoList = document.getElementById("todoList");
let addTodoBtn = document.getElementById("addTodo");
let todoInput = document.getElementById("todoInput");

// 할 일 목록에 이벤트 위임을 설정해요
todoList.addEventListener("click", function(event) {
    if (event.target.tagName === "LI") {
        if (event.target.style.textDecoration === "line-through") {
            event.target.style.textDecoration = "none";
        } else {
            event.target.style.textDecoration = "line-through";
        }
    }
});

// 새 할 일을 추가하는 기능을 만들어요
addTodoBtn.addEventListener("click", function() {
    let newTodo = document.createElement("li");
    newTodo.textContent = todoInput.value;
    todoList.appendChild(newTodo);
    todoInput.value = "";
});

이 문제는 실용적인 할 일 관리 시스템을 통해 동적 이벤트 활용법을 연습하는 데 도움이 돼요.

Ex3) 카드 추가하면 그 카드 중에서 하나만 선택할 수 있게 만들어보자

// 필요한 요소들을 찾아서 변수에 담아요
let cardArea = document.getElementById("cardArea");
let addCardBtn = document.getElementById("addCard");

// 카드 영역에 이벤트 위임을 설정해요
cardArea.addEventListener("click", function(event) {
    if (event.target.classList.contains("card")) {
        // 모든 카드의 선택 상태를 해제해요
        let allCards = cardArea.querySelectorAll(".card");
        for (let i = 0; i < allCards.length; i++) {
            allCards[i].style.backgroundColor = "white";
        }
        // 클릭된 카드만 선택해요
        event.target.style.backgroundColor = "lightblue";
    }
});

// 새 카드를 추가하는 기능을 만들어요
addCardBtn.addEventListener("click", function() {
    let newCard = document.createElement("div");
    newCard.classList.add("card");
    newCard.textContent = "새 카드";
    newCard.style.padding = "20px";
    newCard.style.border = "1px solid gray";
    cardArea.appendChild(newCard);
});

이 연습문제를 통해 카드 선택 시스템에서의 동적 이벤트 활용 방법을 배울 수 있어요.

🤔 심화 문제로 실력 확인하기

기본 연습을 마쳤다면, 이제 조금 더 깊이 있는 문제들을 통해 동적 이벤트에 대한 이해를 확인해볼게요.

Q1. 동적으로 추가된 요소에 기존 이벤트가 적용되지 않는 이유를 설명해보세요.

정답: 이벤트 리스너는 걸려있는 시점에 존재하는 요소들에만 적용되기 때문이에요. addEventListener를 호출할 때 DOM에 없던 요소는 나중에 추가되어도 그 이벤트 리스너의 대상에 포함되지 않아요. 마치 모임 연락망을 만들 때 그 시점에 없던 사람은 연락망에 들어가지 않는 것과 같은 원리예요.

Q2. 다음 코드에서 새로 추가된 버튼이 작동하지 않는 이유를 설명하고 올바르게 수정해보세요.

// 기존 버튼에만 이벤트 걸기
document.querySelectorAll("button").forEach(function(btn) {
    btn.addEventListener("click", function() {
        alert("클릭됨");
    });
});

// 새 버튼 추가 (작동하지 않아요)
function addButton() {
    let newBtn = document.createElement("button");
    newBtn.textContent = "새 버튼";
    document.body.appendChild(newBtn);
}

정답: querySelectorAll은 호출 시점에 존재하던 버튼들에만 이벤트를 걸어주므로, 나중에 추가된 버튼은 이벤트가 없어요. 수정 방법:

// 올바른 방법 - 이벤트 위임 사용
document.body.addEventListener("click", function(event) {
    if (event.target.tagName === "BUTTON") {
        alert("클릭됨");
    }
});

function addButton() {
    let newBtn = document.createElement("button");
    newBtn.textContent = "새 버튼";
    document.body.appendChild(newBtn); // 이제 작동해요
}

해설: 이벤트 위임을 사용하면 부모 요소가 모든 자식의 이벤트를 처리하므로, 언제 추가되든 상관없이 모든 버튼이 작동해요.

📚 11단원 복습문제 - DOM 조작 기억하기

12단원을 마무리하기 전에, 지난 시간에 배운 DOM 조작 내용을 복습해볼까요?

복습 문제 1: HTML 요소 찾기

다음 중 ID가 "myButton"인 요소를 찾는 올바른 방법은?

// A) document.findById("myButton")
// B) document.getElementById("myButton")
// C) document.querySelector("myButton")
// D) document.getElement("myButton")

정답: B) document.getElementById("myButton")가 정답이에요. ID로 요소를 찾을 때는 getElementById를 사용해요.

설명: 11단원에서 배운 DOM 요소 찾기 방법이에요. getElementById는 HTML에서 id 속성으로 요소를 찾는 가장 기본적인 방법이에요.

복습 문제 2: 새 요소 만들고 추가하기

다음 코드에서 빈칸에 들어갈 올바른 코드는?

let newDiv = document._______("div");
newDiv.textContent = "안녕하세요";
document.body._______(newDiv);

정답: createElementappendChild

설명: createElement로 새 요소를 만들고, appendChild로 부모 요소에 추가하는 것이 11단원에서 배운 기본 DOM 조작 방법이에요. 오늘 배운 동적 이벤트도 이 기초 위에서 작동해요.

지금까지 동적 요소에 이벤트를 적용하는 모든 방법을 차근차근 알아보았어요. 이 기법은 현대 웹 개발에서 매우 중요한 기술로, 사용자와 상호작용하는 동적인 웹페이지를 만드는 데 필수적이에요. 마치 새로 이사온 이웃도 자연스럽게 동네의 따뜻한 분위기에 녹아들 수 있게 하는 것처럼, 새로 추가되는 모든 요소들이 자연스럽게 기존 시스템에 통합되도록 만들어주는 따뜻한 기술이에요!

✅ 학습 완료 체크리스트

이번 시간에 배운 내용들을 모두 이해했는지 확인해보세요!

학습 내용 이해했나요?
동적 요소의 기본 개념
기본 사용법과 문법
주요 특징과 차이점
자주 하는 실수들
실전 예제 이해

🎯 추가 연습 문제들

조금 더 연습하고 싶은 친구들을 위한 추가 문제들이에요!

추가 문제 1. 동적으로 버튼을 추가하고 클릭 이벤트가 작동하는 코드를 만들어보세요.

// 답:
let container = document.getElementById("container");
let addBtn = document.getElementById("addBtn");

// 이벤트 위임
container.addEventListener("click", function(event) {
    if (event.target.tagName === "BUTTON") {
        alert("버튼 클릭됨: " + event.target.textContent);
    }
});

// 버튼 추가
addBtn.addEventListener("click", function() {
    let newBtn = document.createElement("button");
    newBtn.textContent = "새 버튼";
    container.appendChild(newBtn);
});

추가 문제 2. 동적 목록 항목에 완료 표시 기능을 추가해보세요.

// 답:
let list = document.getElementById("list");
let addItemBtn = document.getElementById("addItem");

// 항목 클릭 시 완료 토글
list.addEventListener("click", function(event) {
    if (event.target.tagName === "LI") {
        event.target.classList.toggle("completed");
        console.log("항목 상태 변경");
    }
});

// 새 항목 추가
addItemBtn.addEventListener("click", function() {
    let newItem = document.createElement("li");
    newItem.textContent = "새 할 일";
    list.appendChild(newItem);
});

추가 문제 3. 동적 카드에 선택 기능을 구현해보세요.

// 답:
let cardArea = document.getElementById("cardArea");
let addCardBtn = document.getElementById("addCard");

// 카드 선택 이벤트
cardArea.addEventListener("click", function(event) {
    if (event.target.classList.contains("card")) {
        // 기존 선택 해제
        let allCards = cardArea.querySelectorAll(".card");
        for (let i = 0; i < allCards.length; i++) {
            allCards[i].classList.remove("selected");
        }
        // 새 선택
        event.target.classList.add("selected");
    }
});

// 카드 추가
addCardBtn.addEventListener("click", function() {
    let newCard = document.createElement("div");
    newCard.classList.add("card");
    newCard.textContent = "새 카드";
    cardArea.appendChild(newCard);
});

추가 문제 4. 동적으로 추가된 요소에 기존 이벤트 리스너가 적용되지 않는 이유는 무엇인가요?

: 이벤트 리스너는 등록할 때 존재하던 요소에만 적용되기 때문입니다. 나중에 createElement로 만든 요소는 그 시점에 존재하지 않았으므로 기존 이벤트 리스너가 적용되지 않아요.

추가 문제 5. 다음 코드에서 새로 추가된 버튼이 작동하지 않는 이유를 설명하고 수정해보세요.

// 기존 버튼에만 이벤트 등록
document.querySelectorAll("button").forEach(btn => {
    btn.addEventListener("click", () => alert("클릭됨"));
});

// 새 버튼 추가
let newBtn = document.createElement("button");
document.body.appendChild(newBtn);

: 새 버튼은 이벤트 등록 후에 추가되었기 때문에 이벤트가 없습니다. 수정 방법:

document.body.addEventListener("click", function(event) {
    if (event.target.tagName === "BUTTON") {
        alert("클릭됨");
    }
});

let newBtn = document.createElement("button");
document.body.appendChild(newBtn); // 이제 작동함

🔄 단계별 진행 과정 정리

지금까지 배운 내용을 단계별로 다시 한번 정리해볼게요.

1단계 과정: 이벤트 위임 설정 → 버튼 추가 기능 구현 → 새 버튼에 자동으로 이벤트 적용

2단계 과정: 목록에 이벤트 위임 → 입력값으로 새 항목 생성 → 자동 이벤트 적용

3단계 과정: 카드 선택 이벤트 위임 → 카드 생성 기능 → 자동 선택 기능 적용

📂 마무리 정보

오늘 배운 12.3.2 내용이 여러분의 자바스크립트 지식 상자에 잘 저장되었나요? 다음 시간에는 더 재미있는 내용으로 만나요!

기억할 점: 오늘 배운 내용을 꼭 연습해보시고, 궁금한 점이 있으면 언제든 다시 돌아와서 읽어보세요.


🚀 더 체계적인 JavaScript 학습을 원하신다면?
이 포스팅에서 다룬 내용을 실제로 실습해보세요!
무료 JavaScript 학습 플랫폼에서 단계별 학습과 실시간 코드 실행을 통해
더욱 효과적이고 재미있게 학습하실 수 있습니다.
📝 실시간 코드 실행 📊 학습 진도 관리 👥 체계적 커리큘럼
📚 171개 체계적 학습레슨 · 📋 855개 4지선다 연습문제 · 🆓 완전 무료 · ⚡ 즉시 시작