[문벅스 만들기] Step 1. 돔 조작과 이벤트 핸들링으로 메뉴 관리하기

Pulan·2022년 7월 11일
0

moonbucks-menu

🎯 step1 요구사항 - 돔 조작과 이벤트 핸들링으로 메뉴 관리하기

  • 에스프레소 메뉴에 새로운 메뉴를 확인 버튼 또는 엔터키 입력으로 추가한다.
    • 메뉴가 추가되고 나면, input은 빈 값으로 초기화한다.
    • 사용자 입력값이 빈 값이라면 추가되지 않는다.
  • 메뉴의 수정 버튼을 눌러 메뉴 이름 수정할 수 있다.
    • 메뉴 수정시 브라우저에서 제공하는 prompt 인터페이스를 활용한다.
  • 메뉴 삭제 버튼을 이용하여 메뉴 삭제할 수 있다.
    • 메뉴 삭제시 브라우저에서 제공하는 confirm 인터페이스를 활용한다.
  • 총 메뉴 갯수를 count하여 상단에 보여준다.
  • 추가되는 메뉴의 아래 마크업은 <ul id="espresso-menu-list" class="mt-3 pl-0"></ul> 안에 삽입해야 한다.

추가할 코드

<li class="menu-list-item d-flex items-center py-2">
  <span class="w-100 pl-2 menu-name">${name}</span>
  <button
    type="button"
    class="bg-gray-50 text-gray-500 text-sm mr-1 menu-edit-button"
  >
    수정
  </button>
  <button
    type="button"
    class="bg-gray-50 text-gray-500 text-sm menu-remove-button"
  >
    삭제
  </button>
</li>

코드를 짜기전에 미리 계획해뒀던 순서도를 통해 진행하다가 생각이 바뀌었던 부분과 발생한 문제를 기록하게 되었다.

1. 버튼 클릭 / Enter 키 입력

에스프레소 메뉴에 새로운 메뉴를 확인 버튼 또는 엔터키 입력으로 추가한다

라는 요구사항을 통해 처음에는 버튼 클릭, Enter 키 입력에 각각 이벤트 리스너를 줬었는데 보다보니 그냥 각자 이벤트 리스너를 주지않고 그냥 form 태그에서 같이 해결할 수 있을거 같다는 생각이 들었다.

$form.addEventListener('submit', e => {
  e.preventDefault();

  if (!$input.value) {
    alert('메뉴를 입력하세요');
    return;
  }
  addMenuName();
});

이렇게 해결할 때 주의해야 할 점은 html문서에서 button type을 button에서 submit으로 바꾸는 것이다.

2. 메뉴 추가 (고민중)

이 부분은 지금도 생각 중인데 아직도 어떤 방법이 좋은지 잘 모르겠다.
지금 사용하는 코드는 insertAdjacentHTML 메서드를 통해서 추가할 템플릿을 ul 태그 안에 순서대로 삽입하는 형태이다.

const addMenuName = () => {
  const menuName = $input.value;
  const template = menuName => {
    return `
      <li class="menu-list-item d-flex items-center py-2">
  <span class="w-100 pl-2 menu-name">${menuName}</span>
  <button
    type="button"
    class="bg-gray-50 text-gray-500 text-sm mr-1 menu-edit-button"
  >
    수정
  </button>
  <button
    type="button"
    class="bg-gray-50 text-gray-500 text-sm menu-remove-button"
  >
    삭제
  </button>
</li>
    `;
  };

  $menuList.insertAdjacentHTML('beforeend', template(menuName));
  $input.value = '';

  updateMenuCount();
};

여기서 드는 생각은 innerHTML을 이용해서 추가할 템플릿을 통채로 덮어씌우는 것도 나쁘지 않을거 같은데? 라는 생각이 들었다.
근데 그 이유를 아직은 잘 모르겠다. 뒤에서 템플릿을 수정하고 삭제하면서 계속 데이터가 바뀌는 건 알겠는데 아직 개념이 내 머리속에서 제대로 정리가 안된거 같아서 이 부분은 더 공부해야겠다.

3. 수정 / 삭제 버튼 클릭

원래 수정, 삭제 버튼을 구분하기 위해

e.target.innerText == "수정"
e.target.innerText == "삭제"

이러한 형태로 innerText를 사용했는데 추가하는 템플릿에서 수정, 삭제 버튼에 각자 가지고 있는 클래스가 다른 것을 봤다.

class=" ~ / menu-edit-button" -> 수정
class=" ~ / menu-remove-button" -> 삭제

그래서 클래스를 이용하여 아래와 같이 코드를 바꿨다.

$menuList.addEventListener('click', e => {
  //* e.target.innerText == "수정" -> e.target.classList.contains('menu-edit-button')
  if (e.target.classList.contains('menu-edit-button')) {
    updateMenuName(e);
    return;
  }

  //* e.target.innerText == "삭제" -> e.target.classList.contains('menu-remove-button')
  if (e.target.classList.contains('menu-remove-button')) {
    removeMenuName(e);
    return;
  }
});

4. prompt 창에서 cancel시 빈 문자열로 바뀌는 메뉴

이렇게 조건문을 추가하면 정상적으로 작동된다.

if (updatedMenuName === null) return;

참고 자료

profile
현재 개발 중인 블로그로 내용들을 개선하면서 업데이트하고 있습니다. https://www.plu457.life/

0개의 댓글