Skip to content

Conversation

@hansoojeongsj
Copy link
Member

@hansoojeongsj hansoojeongsj commented Apr 25, 2025

🤙🏻 구현 기능 명세

💡 기본 과제

  • HTML, CSS, JavaScript만 사용. (React사용 X)
  1. 데이터

    • 초기 데이터는 데이터 파일을 별도로 생성해서 저장
    • 데이터를 불러와서 localStorage에 저장
    • localStorage 데이터를 이용해서 테이블을 렌더링(HTML에 데이터를 직접 넣는 하드코딩 x)
  2. 상단 섹션(필터링)

    • 전체, 완료됨, 미완료, 중요도 버튼으로 구성
    • 중요도 버튼 안에는 아이콘 포함
    • 전체, 완료됨, 미완료로 해당 조건에 만족하는 todo 필터링
  3. 할 일 추가 섹션

    • input에 할 일, 중요도 선택 후 추가버튼 클릭시 todo 테이블에 추가
    • 둘 중에 하나라도 입력 안하면 alert창 출력 (이 때 테이블에 추가 되지 않음)
    • 추가완료시에 input창에는 다시 placeholder가 보여야함.
  4. todo 테이블

    • HTML의 table 태그를 사용해서 구현
    • 체크박스 기능
  5. 삭제-완료 버튼

    • todo 체크 후 삭제 버튼 클릭시 해당 todo 삭제
    • todo 체크 후 완료 버튼 클릭시 해당 todo 완료됨 표시
    • 이미 완료된 todo가 하나라도 포함되면 모달창 출력 후 완료 반영X

🔥 심화 과제

  1. 상단 섹션(필터링)

    • 중요도 버튼 클릭시 커스텀 드롭다운
    • 중요도 필터링
  2. todo 테이블

    • drag&drop으로 순서 변경 가능 (새로고침 시에도 변경된 순서 유지)
    • 전체 체크박스 기능 (전체가 체크되면 상단 체크박스도 체크됨, 하나라도 해제되면 같이 해제)
  3. 삭제-완료 버튼

    • 전체 체크박스 기능 구현시(심화과제) → 체크 된 todo 일괄삭제

공유과제

제목: 자바스크립트 동기와 비동기

링크 첨부 : https://sweeb.tistory.com/47


🚀 내가 새로 알게 된 점

  • Drag and Drop 구현: dragstart, dragend, dragover, drop 이벤트를 활용하여 리스트 항목을 드래그하여 위치를 변경하는 기능을 구현할 수 있다는 점을 알게 되었습니다. 이를 통해 사용자가 할 일 목록을 재정렬할 수 있도록 했습니다.

  • LocalStorage 활용: 로컬 스토리지를 활용하여 할 일 목록을 브라우저에 저장하고, 새로 고침 후에도 목록을 유지할 수 있다는 점을 배웠습니다. localStorage.getItem과 localStorage.setItem을 통해 데이터를 쉽게 저장하고 불러올 수 있습니다.

  • 조건부 렌더링: filter 버튼을 클릭하여 완료된 작업, 미완료 작업, 모든 작업을 필터링할 수 있도록 조건부 렌더링을 적용하는 방법을 알게 되었습니다. 이를 통해 사용자가 원하는 작업만 필터링하여 볼 수 있습니다.


🤔 구현 과정에서의 어려웠던/고민했던 부분

  • querySelector와 getElementById 선택자 사용에 대한 고민을 했습니다.
    id 값을 기반으로 요소를 선택할 때 getElementById를 사용할지, 아니면 querySelector를 사용할지 고민이 있었습니다. 둘 다 id 값으로 요소를 찾을 수 있지만, querySelector는 더 범용적인 선택자로 CSS 선택자처럼 사용할 수 있기 때문에 코드의 일관성을 위해 querySelector를 사용하는 것이 좋을 수 있다는 생각을 했습니다.

⏳ 소요 시간

  • 8h

🤳🏻 구현 결과물

로컬 스토리지 및 상단 필터링
투두 만들기 - Chrome 2025-04-25 23-24-59

할 일 추가 및 드래그앤드롭
투두 만들기 - Chrome 2025-04-25 23-25-26

전체 체크박스
투두 만들기 - Chrome 2025-04-25 23-43-06

@yeeeww
Copy link

yeeeww commented Apr 29, 2025

2차 과제 수고하셨습니다~!!

Copy link
Member

@maehwasoo maehwasoo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2주차 과제도 고생 많으셨습니다~~! 코드가 전체적으로 깔끔하게 구조화되어 있고 가독성도 좋아서 리뷰하는데 용이했던 것 같습니다 수고하셨습니다 !!

@@ -0,0 +1,181 @@
import { todos as initialTodos } from './data/todos.js';

const todoList = document.getElementById('todo-list');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여러 DOM 요소를 상단에서 한 번에 변수로 저장하는 방식 덕분에 코드의 가독성이 좋은 것 같습니다~~! 👍👍👍

</head>
<body>
<!-- 상단 필터 -->
<nav aria-label="할일 목록 필터">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<nav> 태그를 통해 필터 버튼들을 그룹화하고, aria-label로 내비게이션의 목적을 명확히 한 점이 매우 좋은 것 같습니다! 👍👍

</section>
</main>

<div id="completed-modal" class="modal" hidden>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

모달 팝업시 사용자는 모달 안의 내용에 집중해야 하므로
모달에 role="dialog"와 aria-modal="true" 속성을 추가하면
모달을 인식하고 포커스를 모달 내부로 제한하므로 웹 접근성이 더욱 좋아질 것 같습니다!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 !! 좋은 방법 알려주셔서 감사합니다. 수정하겠습니다 !

renderTodos(todos);

allBtn.addEventListener('click', () => renderTodos(todos));
completedBtn.addEventListener('click', () => renderTodos(todos.filter(todo => todo.completed)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재는 필터 버튼마다 각각 todos를 직접 필터링해서 renderTodos에 넘기고 있는데 이 부분을 하나의 필터 함수 (예를 들어 filterTodos)로 만들어서 필터 버튼 클릭 시 조건만 다르게 넘기도록 수정하면 코드도 줄어들고 가독성과 유지보수도 좋아질 것 같습니다!

function filterTodos({ completed = null, priority = null } = {}) {
    return todos.filter(todo => {
        if (completed !== null && todo.completed !== completed) return false;
        if (priority !== null && todo.priority !== Number(priority)) return false;
        return true;
    });
}

allBtn.addEventListener('click', () => renderTodos(filterTodos()));
completedBtn.addEventListener('click', () => renderTodos(filterTodos({ completed: true })));
uncompletedBtn.addEventListener('click', () => renderTodos(filterTodos({ completed: false })));

const renderTodos = (data) => {
const tbody = todoList.querySelector('tbody');
tbody.innerHTML = '';
data.forEach((todo, index) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 방식은 매번 tbody를 비우고(tr을 전체 삭제) 행을 하나씩 추가하고 있습니다
즉 할 일이 많아질수록 DOM 조작이 많아져 느려질 가능성이 크니,

const renderTodos = (data) => {
    const tbody = todoList.querySelector('tbody');
    tbody.innerHTML = '';

    const fragment = document.createDocumentFragment();
    data.forEach((todo, index) => {
        const tr = document.createElement('tr');

        ...

        fragment.appendChild(tr);
    });
    tbody.appendChild(fragment);

    updateToggleAllCheckbox();
};

documentFragment를 사용하여 fragment에 tr을 모두 추가 후 한 번에 tbody에 붙이는 방식으로 최적화를 한다면 할일이 매우 많아져도 성능 하락이 많이 감소할 것 같습니다!

Copy link
Member

@1jiwoo27 1jiwoo27 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

전체적으로 완성도가 높아서 리뷰하면서 많이 배워가요 🤓
나중에 리팩토링 할 때 참고하겠습니다 ㅎㅎ
2주차 과제도 수고 많으셨습니다 🩶

<main>
<!-- 할일 추가 섹션 -->
<section aria-label="할일 추가하기">
<form>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 다음에는 form 태그를 활용해봐야겠어요!

</head>
<body>
<!-- 상단 필터 -->
<nav aria-label="할일 목록 필터">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

과제하면서 aria-label은 간과하고 있던 것 같은데, 앞으로는 접근성 향상을 위해 넣어볼게요 ✍🏻

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

과제할 때 신경 써줘야 앞으로도 신경쓰기에 쉽더라구요..! 파이팅!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants