step1 요구사항 - 돔 조작과 이벤트 핸들링으로 메뉴 관리하기
- 에스프레소 메뉴에 새로운 메뉴를 확인 버튼 또는 엔터키 입력으로 추가한다.
- 메뉴가 추가되고 나면, input은 빈 값으로 초기화한다.
- 사용자 입력값이 빈 값이라면 추가되지 않는다.
- 메뉴의 수정 버튼을 눌러 메뉴 이름 수정할 수 있다.
- 메뉴 수정시 브라우저에서 제공하는 prompt 인터페이스를 활용한다.
- 메뉴 삭제 버튼을 이용하여 메뉴 삭제할 수 있다.
- 메뉴 삭제시 브라우저에서 제공하는 confirm 인터페이스를 활용한다.
- 총 메뉴 갯수를 count하여 상단에 보여준다.
document.querySelector('button').addEventListener('click', () => {
if (document.querySelector('input').value === '') {
alert('값을 입력해주세요.');
return;
}
const espressoMenuName = document.querySelector('input').value;
const menuItemTemplate = (espressoMenuName) => {
return `
<li class="menu-list-item d-flex items-center py-2">
<span class="w-100 pl-2 menu-name">${espressoMenuName}</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>`;
};
document.querySelector('ul').insertAdjacentHTML(
'beforeend',
menuItemTemplate(espressoMenuName)
);
});
button을 클릭하면 input에 입력한 value의 값을 li 안에 넣어, ul의 자식 노드로 추가한다.
이 과정에서 나는 insertAdjacentHTML 대신, innerHTML을 사용하여 HTML 코드를 삽입하였다.
하나의 메뉴만 추가한다면 옳은 방법이겠지만, 새로운 노드로 교체되기 때문에 여러 개의 메뉴를 추가 되지는 않는다.
강의에서는 insertAdjacentHTML
를 사용하여 ul의 자식 노드로 li를 추가하였다. insertAdjacentHTML는 위치를 지정할 수 있기 때문에, beforebegin / afterbegin / beforend / afterend
4가지의 원하는 위치에 element를 삽입할 수 있다.
const menuCount = document.querySelector('ul').querySelectorAll('li').length;
$('.menu-count').innerText = `총 ${menuCount} 개`;
document.querySelector('ul').addEventListener('click', (e) => {
// 수정 버튼
if (e.target.classList.contains('수정버튼')) {
const $menuName = e.target.closest('li').querySelector('input');
const menuEdit = prompt('메뉴명을 수정하세요.', $menuName.innerText);
if (menuEdit !== null) {
$menuName.innerText = menuEdit;
}
}
});
이벤트 위임
을 활용하여 코드를 작성하였다. 이벤트 리스너를 실행할 작업을 요소의 부모 요소에게 위임(Delegation)할 수 있다. 이벤트 위임의 장점들
- 동적으로 추가되는 요소들에도 동작한다.
- DOM트리에 새로운 요소를 추가하더라도 이벤트에 대한 처리는 부모 요소에게 위임되었기 때문에 새로운 요소에 이벤트 핸들러를 다시 지정할 필요가 없다.
- 코드의 간결
- 이 기법을 이용하면 함수를 많이 작성할 필요가 없으며 DOM과 코드간의 연결이 간소해져 결과적으로 유지보수에 도움이 된다.
classList.contains
를 이용하여 수정 버튼과 삭제 버튼을 두 가지를 구분하였다.(e.target.closest)
li 의 input의 innerText 값을 사용하였다.이벤트 위임, insertAdjacentHTML, closest 등 자바스크립트 메서드들을 적극 활용하여 프로젝트를 진행 해가면서 내가 어떤 점이 부족 했었는지를 알 수 있는 시간이었다. 또한 강의 중간중간에 실무적인 팁들을 알려주셔서 도움이 많이 되었다. (변수 이름 짓기, 요구사항 분석 등)
메뉴를 추가할 때 innerHTML을 사용하였는데, insertAdjacentHTML를 사용하면 더 편리하게 위치를 조정할 수 있는 것을 알게되었고, closest는 강의를 통하여 처음 알게 된 메서드였다. 앞으로도 편리하게 사용할 것 같다.
섹션마다 미션을 통해서 내가 먼저 코드를 구현한 뒤, 강사님의 코드를 보며 리팩토링을 하는 재미가 있었고, 온라인 상이지만 강사님의 훌륭한 강의 덕분에 서로 소통한다는 느낌이 많이 들어서 공부를 더 효율적으로 할 수 있었다.