
JavaScript 로 메뉴 카테고리 구현하기
기능 설명
1. 메뉴 추가를 누르면 input text 창이 나오고, 해당 내용 입력 후 저장을 누르면 하위카테고리가 생김
2. 가장상위(depth) 는 전체보기를 클릭후 메뉴추가
3. 삭제하고자 하는 메뉴를 클릭 후 삭제버튼을 누르면 삭제됨.
4. 다만 하위항목이 존재할경우 삭제가 되지 않음
5. 별도의 DB가 없이 LocalStorage 를 이용하여 저장할 예정
1. script 를 제외한 head~body 부분
<!DOCTYPE html> <html lang="ko"> <head> <title>메뉴</title> <style> .highlight { background-color: yellow; } #itemList > li { list-style-type: none; } </style> </head> <body> <h1>메뉴 관리</h1> <button id="add">메뉴 추가</button> <form id="itemForm"> <ul id="itemList"> <li class="highlight" id="0"><h1>전체보기</h1></li> </ul> <button id="submit">메뉴 저장</button> </form><br> <button id="delete">삭제</button>
itemList 에 이제 script 를 이용하여 동적으로 메뉴를 생성
Script 부분
1. list 항목 추가 후 appendChild 를 통하여 동적으로 메뉴 리스트 추가
var mylist = []; mylist.push({"id" : "1", "parent":null, "text": "1번데이터"}); mylist.push({"id" : "2", "parent":null, "text": "2번데이터"}); mylist.push({"id" : "3", "parent":"1", "text": "3번데이터"}); mylist.push({"id" : "4", "parent":"3", "text": "4번데이터"}); mylist.push({"id" : "5", "parent":null, "text": "5번데이터"}); mylist.push({"id" : "6", "parent":"2", "text": "6번데이터"}); mylist.push({"id" : "7", "parent":null, "text": "7번데이터"}); /* mylist 는 id 값과 parent (하위항목일경우 parent의 id 찾기 위한 값), 내용이 들어갈 text (사실상 value) 로 만들었음 */ //초기 로드일 경우 mylist 를 이용하여 화면에뿌림, 수정을 거쳤을 경우 해당 내용으로. if(!localStorage.getItem('myItemList')){ localStorage.setItem('myItemList', JSON.stringify(mylist)); } mylist = JSON.parse(localStorage.getItem('myItemList')); let length = mylist.length; let count = length; //forEach 를 이용하여 각 list 를 그리는데, pid(parent) 가 있을 경우 해당 하위항목으로 위치시킴 mylist.forEach(element => { let li = document.createElement('li'); li.id = element.id; li.textContent = element.text; let ul = document.createElement('ul'); ul.id = element.id; if(element.parent != null){ document.getElementById(element.parent).appendChild(ul); ul.appendChild(li); // itemList.appendChild(ul); }else{ document.getElementById("itemList").appendChild(ul); ul.appendChild(li); //itemList.appendChild(li); } });
2. 선택시 하이라이트 효과 및 선택한 메뉴에 event 를 적용하기 위한 class 동적 추가 (삭제나 하위항목 추가에 사용)
//itemList 에 EventListener 추가 document.querySelectorAll('#itemList li').forEach(li => { li.addEventListener('click', (event)=>{ // 하위요소가 없으면 highlightElement 실행 if (!li.querySelector('ul')) { highlightElement(li); } // 부모요소까지 이벤트 미치지 못하도록 event.stopPropagation(); }) }) //highlight 라는 class 를 추가(style css 보면 highlight 설정해둔 것을 알 수 있음) const highlightElement = element => { document.querySelectorAll('#itemList li').forEach(li =>{ li.classList.remove('highlight'); }); element.classList.add('highlight'); }
3. 항목 선택 후 메뉴 추가 이벤트
document.getElementById('add').addEventListener('click', function() { var highlightedElement = document.querySelectorAll('.highlight')[0]; let ul = document.createElement('ul'); ul.id=highlightElement.id; let li = document.createElement('li'); let pid = highlightedElement.id==0 ? null : highlightedElement.id count++; li.innerHTML = `<input type='text' class='addMenu' id=`+count+` name=`+pid+` required></input>`; ul.appendChild(li); highlightedElement.insertAdjacentElement('afterend', ul); }); //innerHTML 에 input 을 넣었고, appendChild 를 통하여 선택한 하위메뉴에 들어가도록 함.
4. 메뉴 추가 후 저장버튼으로 메뉴 수정
document.getElementById('itemForm').addEventListener('submit', function(event) { event.preventDefault(); // 기본 제출 동작 방지 let inputValues = []; let inputs = document.querySelectorAll('input[type="text"]'); inputs.forEach(function(input) { let inputId = input.id; let inputName = input.name == "null" ? null : input.name; console.log(inputName); let inputText = input.value; mylist.push({"id" : inputId, "parent":inputName, "text": inputText}) }); console.log("after" + mylist); //LocalStorage 에 저장한 list (myItemList) 업데이트 localStorage.setItem('myItemList', JSON.stringify(mylist)); location.reload(); });
5. 삭제버튼 클릭시 이벤트
//삭제 버튼 클릭시 이벤트 실행. mylist 에서 해당항목 splice 를 통해 삭제 후 리로드로 화면을 다시 그림 document.getElementById('delete').addEventListener('click', function() { event.preventDefault(); // 기본 제출 동작 방지 var highlightedElement = document.querySelectorAll('.highlight')[0]; let id = highlightedElement.id; if(checkParent(id)){ alert("하위항목이 남아있습니다.") }else{ for (let i = mylist.length -1 ; i>=0 ; i--){ if(mylist[i].id === id){ mylist.splice(i, 1); } } } localStorage.setItem('myItemList', JSON.stringify(mylist)); location.reload(); }); //하위 항목이 존재하는지 확인 function checkParent(id){ for(let i = mylist.length - 1 ; i >= 0 ; i--){ if(mylist[i].parent==id){ return true; } } return false; }