다른 탭에서도 todo list를 사용할 수 있는 방법이 있을까요 ? - javascript
조회수 403회
todo list를 두 가지 목적(프로젝트, 개인)으로 사용할 수 있도록 javascript, html, css로 제작 중 인데요. 번갈아 가며 사용 가능해야 하는데 , 첫 번째 탭에서는 정상 작동하나, 두 번째 탭에서 작동하지 않습니다. 실행하자 마자 두번째 탭을 먼저 들어가도 작동하지 않습니다. 제 생각엔 실행 순서에 문제가 있는 것 같지만, 아닐 수도 있습니다... 어떻게 고칠 수 있을까요 ? 하단은 javascript의 코드입니다 !
const todoObjectList1 = [];
const todoObjectList2 = [];
// 탭 전환
$(".menu1").click(function(){
$(this).addClass('on');
$(".menu2").removeClass("on");
})
$(".menu2").click(function(){
$(this).addClass('on');
$(".menu1").removeClass("on");
})
// project todo
class Todo_Class1 {
constructor(item){
this.ulElement1 =item;
}
add() {
const todoInput1 = document.querySelector("#myInput1").value;
if (todoInput1 == "") {
alert("You did not enter any item!")
} else {
const todoObject1 = {
id1 : todoObjectList1.length,
todoText1 : todoInput1,
isDone1 : false,
}
todoObjectList1.unshift(todoObject1);
this.display();
document.querySelector("#myInput1").value = '';
}
}
done_undone(x) {
const selectedTodoIndex1 = todoObjectList1.findIndex((item)=> item.id1 == x);
console.log(todoObjectList1[selectedTodoIndex1].isDone1);
todoObjectList1[selectedTodoIndex1].isDone1 == false ? todoObjectList1[selectedTodoIndex1].isDone1 = true : todoObjectList1[selectedTodoIndex1].isDone1 = false;
this.display();
}
deleteElement(z) {
const selectedDelIndex1 = todoObjectList1.findIndex((item)=> item.id1 == z);
todoObjectList1.splice(selectedDelIndex1,1);
this.display();
}
display() {
this.ulElement1.innerHTML = "";
todoObjectList1.forEach((object_item1) => {
const liElement1 = document.createElement("li");
const delBtn1 = document.createElement("i");
liElement1.innerText = object_item1.todoText1;
liElement1.setAttribute("data-id1", object_item1.id1);
delBtn1.setAttribute("data-id1", object_item1.id1);
delBtn1.classList.add("far", "fa-trash-alt");
liElement1.appendChild(delBtn1);
delBtn1.addEventListener("click", function(e) {
const deleteId1 = e.target.getAttribute("data-id1");
myTodoList1.deleteElement(deleteId1);
})
liElement1.addEventListener("click", function(e) {
const selectedId1 = e.target.getAttribute("data-id1");
myTodoList1.done_undone(selectedId1);
})
if (object_item1.isDone) {
liElement1.classList.add("checked");
}
this.ulElement1.appendChild(liElement1);
})
}
}
// personal todo
class Todo_Class2 {
constructor(item){
this.ulElement2 =item;
}
add() {
const todoInput2 = document.querySelector("#myInput2").value;
if (todoInput2 == "") {
alert("You did not enter any item!")
} else {
const todoObject2 = {
id2 : todoObjectList2.length,
todoText2 : todoInput2,
isDone2 : false,
}
todoObjectList1.unshift(todoObject2);
this.display();
document.querySelector("#myInput2").value = '';
}
}
done_undone(x) {
const selectedTodoIndex2 = todoObjectList2.findIndex((item)=> item.id2 == x);
console.log(todoObjectList2[selectedTodoIndex2].isDone2);
todoObjectList2[selectedTodoIndex2].isDone2 == false ? todoObjectList1[selectedTodoIndex2].isDone2 = true : todoObjectList2[selectedTodoIndex2].isDone2 = false;
this.display();
}
deleteElement(z) {
const selectedDelIndex2 = todoObjectList2.findIndex((item)=> item.id2 == z);
todoObjectList2.splice(selectedDelIndex2,1);
this.display();
}
display() {
this.ulElement2.innerHTML = "";
todoObjectList2.forEach((object_item2) => {
const liElement2 = document.createElement("li");
const delBtn2 = document.createElement("i");
liElement2.innerText = object_item2.todoText2;
liElement2.setAttribute("data-id2", object_item2.id2);
delBtn2.setAttribute("data-id2", object_item1.id2);
delBtn2.classList.add("far", "fa-trash-alt");
liElement2.appendChild(delBtn2);
delBtn2.addEventListener("click", function(e) {
const deleteId2 = e.target.getAttribute("data-id2");
myTodoList2.deleteElement(deleteId2);
})
liElement2.addEventListener("click", function(e) {
const selectedId2 = e.target.getAttribute("data-id2");
myTodoList1.done_undone(selectedId2);
})
if (object_item2.isDone) {
liElement2.classList.add("checked");
}
this.ulElement2.appendChild(liElement2);
})
}
}
////-----MAIN PROGRAM------------
const listSection1 = document.querySelector("#myUL1");
myTodoList1 = new Todo_Class1(listSection1);
// project todo add
document.querySelector(".addBtn1").addEventListener("click", function() {
myTodoList1.add()
})
document.querySelector("#myInput1").addEventListener("keydown", function(e) {
if (e.keyCode == 13) {
myTodoList1.add()
}
})
// personal todo add
const listSection2 = document.querySelector("#myUL2");
myTodoList2 = new Todo_Class2(listSection2);
document.querySelector(".addBtn2").addEventListener("click", function() {
myTodoList2.add()
})
document.querySelector("#myInput2").addEventListener("keydown", function(e) {
if (e.keyCode == 13) {
myTodoList2.add()
}
})
-
(•́ ✖ •̀)
알 수 없는 사용자 - 〉
1 답변
-
일단, 작동하지 않는 이유는,
Todo_Class2
에서todoObjectList1
을 참조하려는 데가 있기 때문입니다. 잘 찾아보세요. 찾기 어려우실 겁니다. 이런 식으로 코딩을 하고 계신 한, 앞으로도 그 어려운 버그 찾기 작업은 계속될 거구요.이참에 가만히 생각해 봅시다. 왜
Todo_Class2
가 따로 새로 정의돼야 하나요?Todo_Class1
과Todo_Class2
의 차이는 오직 사용할 속성명들뿐이지 않나요?data-id1
이며#myInput1
이며 하는 것들 말이죠.기왕에 클래스 개념을 도입할 거라면, 이런 식으로 되어야 하는 거 아닐까요?
const TodoApp = function (container) { // React에서 "state"라고 부르는 그런 것을 정의한다 let items = []; // 기능들을 잔뜩 정의한다 let appendItem = function (item) { items.push(item); this.render(); }; let render = function () { container.innerHTML = '<ul class="list">' + this.getItems() + '</ul>'; }; let getItems = function () { /* items를 가지고 li 태그의 목록을 만들어야 함 */ }; // 이벤트에 기능을 연결한다 container.queryElementsAll('li').addEventListener('click', function () { /* 입력을 받아 this.appendItem을 실행해야 함 */ }); // 필요한 것만 노출한다 return { render: this.render }; }; // 그러면 얘가 관리하는 items 배열이 따로 있고 let TodoAppFoo = new TodoApp(document.getElementById('#foo')); TodoAppFoo.render(); // 얘가 관리하는 items 배열이 따로 있을 것 let TodoApp2 = new TodoApp(document.getElementById('#todo2')); TodoApp2.render();
핵심은, container는 한번만 지정하게 하고, 나머지는 모두 그 container에 대한 상대적인 요소/기능으로서 작동하도록 만들자는 겁니다. 리액트 같은 프레임워크들이 대체로 이런 아이디어를 갖고 있죠. 그렇게 하면 클래스는 정말 일반론적인 행동 규칙만 갖게 되므로 어떤 container에 대해서든지 작업을 할 수 있고, 어떤 탭에서든지 독립적으로 작동할 겁니다.
참고가 되면 좋겠네요. 한번 연구해 보세요!
- 그렇군요 ! 나중에 DB를 연결하여 두 가지 todo를 따로 관리 할 예정이라 두 개를 만들어야만 하는 줄 알았습니다. 정말 좋은 예시가 될 것 같습니다. 적어주신 코드 바탕으로 수정해 볼게요 ! 정말 감사합니다 !! 알 수 없는 사용자 2021.10.7 00:28
- 기왕 하실 거라면 처음부터 React나 Vue로 하시는 쪽을 강력 추천 드립니다. 애초에 지금 적은 저 코드는 테스트도 안해봤거든요 😅 엽토군 2021.10.7 00:33
- 그러게요... 수정할 엄두가 안 나네요 ㅠㅠ 😶 이참에 React로 갈아타야겠습니다... 정말 감사드려요 ! 알 수 없는 사용자 2021.10.7 00:45
댓글 입력