확인한 환경과 범위

Chromium 156.0.8078.74. 본문의 HTML·CSS·JavaScript를 실제 브라우저로 렌더링하고 현재 화면을 캡처했습니다. 모든 조작·레이아웃·접근성을 검증한 것은 아닙니다.

이 글의 순서 4개 단락

이번 강의에서는 할 일 목록에 현재 항목 수와 빈 목록 안내를 더합니다. 앞 강의에서 만든 추가·삭제 기능을 포함한 전체 파일도 제공하므로, 이전 파일이 없어도 시작할 수 있습니다.

완성 후에는 처음 화면, 빈 입력, 여러 항목의 추가와 삭제를 차례로 점검합니다. 이 예제는 목록을 저장하지 않으므로 새로고침하면 화면이 처음 상태로 돌아갑니다.

목록에서 현재 상태 읽기

목록의 각 할 일은 <li> 요소입니다. 목록 요소의 children.length를 읽으면 현재 들어 있는 항목 수를 알 수 있습니다. 이 예제의 목록에는 할 일 <li>만 직접 추가하므로 이 값이 할 일 개수와 같습니다.

function updateListState() {
  const count = todoList.children.length;
  countText.textContent = `할 일 ${count}개`;
  emptyMessage.hidden = count > 0;
}

textContent는 개수 문구를 바꿉니다. hidden은 요소를 숨길지 정하는 속성입니다. 항목이 하나라도 있으면 count > 0이 참이 되어 빈 목록 안내를 숨기고, 개수가 0이면 다시 보여 줍니다.

목록이 바뀔 때마다 이 함수를 호출해야 표시도 함께 바뀝니다. 따라서 항목을 추가한 직후와 삭제한 직후에 각각 호출합니다. 페이지를 처음 열었을 때도 한 번 호출해 초기 표시를 맞춥니다.

실행할 전체 파일

아래 내용을 index.html로 저장하고 브라우저에서 여세요. HTML, CSS, JavaScript가 모두 들어 있어 별도 파일이 필요하지 않습니다. 입력한 글자는 textContent로 넣으므로 HTML 태그가 아니라 일반 글자로 표시됩니다.

<!doctype html>
<html lang="ko">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>나의 할 일</title>
  <style>
    body {
      max-width: 560px;
      margin: 40px auto;
      padding: 0 20px;
      font-family: sans-serif;
      line-height: 1.5;
      color: #202938;
    }
    .input-row { display: flex; gap: 8px; }
    input { flex: 1; min-width: 0; padding: 8px; }
    button { padding: 8px 12px; cursor: pointer; }
    #message { color: #a12a2a; min-height: 1.5em; }
    #todo-list { padding: 0; list-style: none; }
    #todo-list li {
      display: flex;
      align-items: center;
      justify-content: space-between;
      gap: 12px;
      padding: 8px 0;
      border-bottom: 1px solid #ddd;
    }
    #todo-list li span { overflow-wrap: anywhere; }
  </style>
</head>
<body>
  <main>
    <h1>나의 할 일</h1>
    <div class="input-row">
      <label for="todo-input">할 일</label>
      <input id="todo-input" type="text" placeholder="할 일을 입력하세요">
      <button id="add-button" type="button">추가</button>
    </div>
    <p id="message" role="status"></p>
    <p id="count" aria-live="polite"></p>
    <p id="empty-message">아직 할 일이 없습니다.</p>
    <ul id="todo-list"></ul>
  </main>
  <script>
    const todoInput = document.querySelector('#todo-input');
    const addButton = document.querySelector('#add-button');
    const message = document.querySelector('#message');
    const countText = document.querySelector('#count');
    const emptyMessage = document.querySelector('#empty-message');
    const todoList = document.querySelector('#todo-list');

    function updateListState() {
      const count = todoList.children.length;
      countText.textContent = `할 일 ${count}개`;
      emptyMessage.hidden = count > 0;
    }

    addButton.addEventListener('click', function () {
      const text = todoInput.value.trim();

      if (text === '') {
        message.textContent = '할 일을 입력해 주세요.';
        return;
      }

      message.textContent = '';
      const item = document.createElement('li');
      const itemText = document.createElement('span');
      const deleteButton = document.createElement('button');

      itemText.textContent = text;
      deleteButton.textContent = '삭제';
      deleteButton.type = 'button';
      deleteButton.setAttribute('aria-label', `${text} 삭제`);
      deleteButton.addEventListener('click', function () {
        item.remove();
        updateListState();
      });

      item.append(itemText, deleteButton);
      todoList.append(item);
      todoInput.value = '';
      updateListState();
    });

    updateListState();
  </script>
</body>
</html>

목록 상태 표시와 최종 점검 — 첫 예제의 실제 실행 결과

추가 버튼을 누르면 공백을 제거한 입력값을 먼저 검사합니다. 유효한 값일 때만 항목과 해당 항목의 삭제 버튼을 만들고 목록에 붙입니다. 삭제 버튼은 자신을 만들 때 연결된 item을 지운 뒤 상태를 갱신합니다. 따라서 여러 항목 중 누른 버튼에 해당하는 항목 하나만 제거됩니다.

직접 점검하기

위 파일을 연 뒤 다음 순서대로 확인해 보세요. 아래 내용은 예상 동작이며, 직접 실행해 확인하는 과정입니다.

  1. 처음 화면에 할 일 0개와 아직 할 일이 없습니다.가 표시되는지 확인합니다.
  2. 입력창을 비우거나 공백만 입력한 채 추가를 누릅니다. 안내 문구가 나타나고 개수는 0으로 유지되어야 합니다.
  3. 책 읽기와 산책하기를 각각 추가합니다. 안내 문구와 빈 목록 안내가 사라지고 두 항목과 할 일 2개가 표시되어야 합니다. 추가할 때마다 입력창도 비워집니다.
  4. 첫 번째 항목의 삭제를 누릅니다. 두 번째 항목만 남고 개수는 1이 되어야 합니다.
  5. 남은 항목도 삭제합니다. 개수가 0이 되고 빈 목록 안내가 다시 나타나야 합니다.
  6. 항목을 다시 추가한 다음 페이지를 새로고침합니다. 저장 기능이 없으므로 항목이 사라지고 처음 화면으로 돌아가야 합니다.

개발자 도구의 콘솔에도 오류가 없는지 살펴보세요. 요소를 찾을 수 없다는 오류가 보이면 HTML의 id와 JavaScript의 선택자가 일치하는지, 스크립트가 해당 요소들 뒤에 놓였는지 확인합니다. 개수만 바뀌지 않는다면 추가와 삭제 뒤에 updateListState()를 호출했는지 확인해 보세요.

연습

세 항목을 추가한 뒤 가운데 항목만 삭제해 보세요. 남은 두 항목의 순서와 개수 표시를 확인합니다. 이어서 두 항목을 모두 삭제하고 빈 목록 안내가 돌아오는지 확인하세요.

한 줄씩 이해하고, 차곡차곡 기록합니다.이 글의 오류 제보하기 ↗