DOM 복습 2탄 (feat.Vanilla JS)

📅 TIL #144




🎯 Achievement Goals

  1. post 추가 기능
  2. filtering 기능 구현







Intro.


지난 번에 구현했던 코드에 이어서 이번에는 컨텐츠 추가 기능과 filtering 기능에 대해 블로깅하려고 한다.


이 모든 내용은 코드스테이츠 수강 중에 구현했었던 기능이고 복습 차원에서 다시 해보았다! 기능 자체는 어렵지 않았지만 DOM API를 연습할 겸 복습을 해보았다.




post 추가 기능


addContent


구현 방식은 다음과 같다.


  1. 자식 노드를 전부 제거해주는 함수를 만든다.
  2. submit 버튼을 누르면 외부 변수에 새로운 데이터를 추가해준다.
  3. 그리고 자식 노드를 전부 제거해주는 함수를 호출한다.
  4. 그리고 새로운 데이터와 함께 다시 렌더링한다.


// TODO: 이 코드를 통해 자식 노드 전부 제거
const postLists = document.getElementById('post-list');

function removeAllPost() {
  while(postLists.hasChildNodes()) {
    postLists.removeChild(postLists.firstChild);
  }
}


const DATABASE = [];

function submitPost() {
  const inputId = document.getElementById('input__value-id');
  const inputTitle = document.getElementById('input__value-title');
  const submitBtn = document.getElementById('post-submit');
  
  submitBtn.addEventListener('click', (e) => {

    const newPost = {
      //post data
    }

    // 외부 변수에 저장해둔 데이터에 새로운 데이터를 추가해준다.
    DATABASE.unshift(newPost);

    // 기존 post 전부 제거
    removeAllPost();

    // 추가된 새로운 데이터와 함께 다시 렌더링
    render();

    inputId.value = '';
    inputTitle.value = '';
  })
};

submitPost();


코드 스테이츠 초창기때 했던 방식이라 코드 자체는 쉬웠지만, React를 배운 상태에서 다시 보니 문제점이 많은 코드이다. 렌더링 측면에서 React DOM은 확실히 강점을 보인다. 그래도 간단하게 post를 추가하는 기능을 구현하면서 DOM을 복습해서 좋았다!


이제 post를 클릭하면 filtering이 되는 기능을 구현해볼 차례이다.




filtering 기능 구현


filtering


필터링 기능은 다음과 같이 구현했다.


  1. 모든 포스트를 불러 온다.
  2. 포스트에 이벤트를 추가한다.
  3. 타겟된 태그의 name과 기존의 데이터에서 name을 filter 함수를 통해 필터링한다.
  4. 필터링된 노드는 외부 변수에 저장한다.
  5. 모든 자식 노드를 제거한다.
  6. 필터링된 노드만 렌더링 함수에 전달해서 렌더링한다.


const posts = doc.querySelectorAll('.post-title');

// forEach를 통해 모든 노드에 이벤트를 추가한다.
posts.forEach((post) => {
  filtering(post);
});


let filtered = [];

function filtering(post) {
  post.addEventListener('click', (e) => {
    const title = e.target.textContent;

    // 외부 데이터와 현재 클릭된 타겟의 타이틀을 비교해서 찾는다.
    filtered = DATABASE.filter(v => v.title === title);

    // 자식 노드 전부 제거
    removeAllPost();

    // 필터링된 노드만 렌더링한다.
    // 스케쥴링 사용
    setTimeout(() => {
      postRequest(filtered, 0, filtered.length);
    }, 0)
  });
}


여기서 끝이 아니다. 위의 코드들을 하나의 함수로 묶어준다. 그리고 이전에 post 태그들을 만들어주는 함수를 구현했었는데, 그 함수 안에서 실행시켜 주면 끝이다.


function filterPost() {
  // 위의 코드들이 담겨있다고 생각한다.
  const posts = doc.querySelectorAll('.post-title');

  posts.forEach((post) => {
    filtering(post);
  });

  // ... 생략

  setTimeout(() => {
      postRequest(filtered, 0, filtered.length);
  }, 0)
}

function postRequest(data, start, end) {
  // Post 노드를 만들어 주는 함수
  makePost(title, thumbnailUrl, id);

  // 여기서 filter 함수를 실행시킨다.
  filterPost();
}


필터링 함수는 post를 추가해주고 거기서 필터링한다고 생각하면 쉽다.







마무리.

예전에는 하루 종일해도 어려웠던 코드들을 가지고 쉽게 구현하면서 복습을 하니 재밌었다. 다만 한가지 아쉬운 점은 post를 추가할 때나 필터링할 경우에, post를 모두 제거했다가 다시 렌더링하는 구조가 아쉽다.

이 부분에서 스켈레톤 로딩을 사용해서 UI를 더 신경쓰면 좋겠다는 생각을 했다. 학습 목표는 DOM 복습이니 일단 학습 목표대로 잘 마쳐서 만족스럽다.




Git Repositories