모멘툼을 직접 계속 사용하면서 생각하고,
사용하는 다른 친구들한테도 피드백 받았던 기능들은 전부 구현을 끝냈다!
아직 코드 리팩토링이랑
css 파일 분할을 못했지만 브라우저는 완성된 셈이다.
기간을 딱 픽스하고 한 것이 아니라,
다른 것 하면서 매일 조금씩 한 것이라서 "해냈다!!" 보다는 뭔가
해야할 것.. 질질 끌던 것.. 드디어 끝냈다!!! 같다 ㅎㅎ
이것들 외에도 자잘하게 수정하던 것들이 많지만,, 기억이 안나서 굵직한 것들로만 가지고 왔다.
...
+ 생각해보니 아직 페이지 새로고침 시.. 배경화면 로딩 시간이... 긴 문제는 해결하지 못했네..ㅎ
1. 체크 박스 클릭 한 것을 자동으로 리스트 끝으로 보내기
이유) 이것은 사용하다 보니 순서대로 끝내는 것이 아니라서, 들쭉 날쭉으로 체크된 것이 보기 싫어서 고민하다가 구현했다.
문제와 해결) 구현 시 제일 어려웠던 것은 "어떻게" 끝으로 보낼 것인가.
1. 처음에는 아직도 컴퓨터적인 사고를 못해서 어떻게 내릴 지를 고민했는데 검색을 하다보니,
--> 현재 위치에서 "지우고 splice()", 맨 밑에 다시 "추가 push()" 하면 되어서 checkedMoveTodo 함수를 만들었음
2. 새로고침을 해야지만, 계속 리스트의 끝에 추가되고 바로 적용이 안됨
- gpt 와 계속 싸우기 시작...
- 문제의 원인을 계속 찾지 못하고, 구현에 문제가 없다는 이야기를 반복하고,
나 역시, 콘솔 상에 안나오는데 에러도 없다.. 디버깅이 안된다를 반복했음.
- 결국 reload 버튼을 만들어서 누르게 하려다가
- 전체 코드를 다시 살펴보는데..
// 목록에서 해당 li 요소 삭제
toDoList.removeChild(li);
// 목록의 마지막에 다시 추가
toDoList.appendChild(li);
......ㅎ 화면 상 보이게 안 했으니,, 새로고침을 해야지만 나타나는 것이었다.
--> 위 코드를 추가함.
3. 코드가 너무 겹침.
- 이미 checkToDo 함수가 있고 겹치는 부분이 많아서, 기존 코드에 추가하는 것으로 --> 리팩토링함.
function checkToDo(event) {
//체크박스 줄 그어지는 것 만들어주려고
const checkbox = event.target; //무조건 따로 정의를 해줄 것
const text = checkbox.nextElementSibling; // 체크박스 다음 요소인 텍스트 가져오기
const li = checkbox.parentElement; // li 요소를 가져옵니다.
// 체크된 상태인 경우에만 마지막으로 이동시킵니다.
if (checkbox.checked) {
// 목록에서 해당 li 요소를 삭제합니다.
toDoList.removeChild(li);
// 목록의 마지막에 다시 추가합니다.
toDoList.appendChild(li);
}
if (checkbox.checked) {
text.style.textDecorationLine = "line-through";
} else {
text.style.textDecorationLine = "none";
}
// 변경된 체크박스 상태를 로컬 스토리지에 저장
const todoId = li.id; // 부모 요소인 li의 id 가져오기
const index = toDos.findIndex((todo) => todo.id.toString() === todoId); // 해당 id를 가진 todo의 인덱스 찾기
if (index !== -1) {
toDos[index].checked = checkbox.checked; // 해당 todo의 checked 속성 업데이트
if (checkbox.checked) {
const checkedItem = toDos.splice(index, 1)[0]; //index 위치의 1개를 제거하되, [0] 제거한 인덱스의 1번째 즉 제거한 것 반환
toDos.push(checkedItem);
}
saveToDos(); // 변경된 todo 리스트를 다시 저장
}
}
2. 체크 박스 삭제 버튼 만들기
이유) 하나씩 체크된 것을 삭제시키기가 귀찮아서 만들게 됨.
문제와 해결) 기능과 css 문제가 있었음.
1. 기능 구현을 했는데 코드에 따라서 새로고침 때마다 저장이 안됨.
--> 함수의 위치를 바꾸고, 기존 코드를 최대한 살려서 만들고, saveToDos() 추가
--> forEach로 체크된 것 훓어서 지우도록 만듦.
2. deleteChecked() 하나의 함수로 끝내고 싶었으나, 그럼 루틴에서 체크된 것도 동시에 삭제.
--> 코드 분리해서 각각 deleteCheckedTodo()와 deleteCheckedRoutine() 함수로 만들어줌.
3. html에 버튼을 넣어서 스크롤에 따라서 같이 움직이고, 리스트 위 아래에 고정되게 만들고 싶었으나 실패.
- list class에 postion: relative를 넣고, btn에 position: absolute를 넣었으나, 계속 리스트가 아닌 body를 부모로 인식해서 실패함.
--> 휴지통 버튼의 위치를 to-do form 옆으로 옮기고 form에 display: flex를 줘서 align 한 것으로 만족.. ㅎ
# css
.routine__btn__delete {
position: fixed;
top: 140px;
left: 170px;
border: none;
font-size: 15px;
background: transparent;
color: aliceblue;
transition: transform 0.3s ease-in-out;
}
#todo-form {
display: flex;
justify-content: center;
text-align: center;
align-items: center;
font-size: 30px;
padding-top: 20px;
padding-bottom: 10px;
margin-top: 0;
margin-bottom: 0;
}
.todo__btn__delete {
padding: 20px 6px 10px 6px;
border: none;
font-size: 15px;
background: transparent;
color: aliceblue;
transition: transform 0.3s ease-in-out;
}
.routine__btn__delete:hover,
.todo__btn__delete:hover {
color: steelblue;
background-color: aliceblue;
border: none;
border-radius: 15px;
}
# js
const toDoDeleteBtn = document.querySelector(".todo__btn__delete");
const routineDeleteBtn = document.querySelector(".routine__btn__delete");
function deleteCheckedTodo() {
const checkboxes = document.querySelectorAll(
"#todo-list input[type='checkbox']:checked"
);
checkboxes.forEach((checkbox) => {
const li = checkbox.parentElement;
li.remove();
toDos = toDos.filter((toDo) => toDo.id !== parseInt(li.id));
});
saveToDos();
}
function deleteCheckedRoutine() {
const routineCheckboxes = document.querySelectorAll(
"#routine-list input[type='checkbox']:checked"
);
routineCheckboxes.forEach((checkbox) => {
const li = checkbox.parentElement;
li.remove();
routineToDos = routineToDos.filter(
(routine) => routine.id !== parseInt(li.id)
);
});
saveRoutines();
}
toDoDeleteBtn.addEventListener("click", deleteCheckedTodo);
routineDeleteBtn.addEventListener("click", deleteCheckedRoutine);
3. 투두 리스트 수정하기
이유) 처음에는 그냥 지우고 만들지 하다가, 그렇게 되면 리스트가 밀리고, 친구의 요청으로 추가.
문제와 해결) 기능 구현이 오래 걸렸고, 저장 문제가 있었음.
1. 기능 구현을 할 때 event.target 변수를 빼먹어서 구현이 계속 안 됐음.
--> gpt 조언대로 해도 계속 구현이 안 되서 기존 코드를 살피면서 전면 수정했음.
--> this를 굳이 쓸 필요가 없어서 제외했고, text가 써진 span을 가지고 와야 하는 데 그것을 생각하지 못해서 오래 걸렸음.
--> attribute = "contenteditable" 수정을 위한 속성을 배움.
--> 인덱스를 찾은 경우 innerText가 변경되도록 구현.
function editToDo(event) {
const editBtn = event.target;
const li = editBtn.parentElement;
const editText = li.querySelector("span"); // span 요소를 찾음
if (editText) {
// editText가 null이 아닌 경우에만 실행
editText.setAttribute("contenteditable", true); // 편집 가능하도록 설정
editText.focus(); // 편집 상태로 이동
editText.addEventListener("blur", () => {
// 포커스를 잃으면
editText.removeAttribute("contenteditable"); // contenteditable 속성 제거하여 편집 완료
const todoId = li.id;
const index = toDos.findIndex((todo) => todo.id === parseInt(todoId));
// -1은 특정 아이템을 찾지 못했을 때 반환하는 값
if (index !== -1) {
toDos[index].text = editText.innerText;
saveToDos();
}
});
}
}
2. 이 경우는 html에 추가 할 필요 없이 리스트가 생성될때 나타나도록 할 때 fontawesome 넣고 싶었음.
--> setattribute에 class로 넣어도 되는 데.. 개인적으로 이게 더 직관적이라고 느껴져서 이렇게 함.
function paintToDo(newTodo) {
...
const editBtn = document.createElement("button");
editBtn.innerHTML = '<i class="fa-regular fa-pen-to-square"></i>';
editBtn.addEventListener("click", editToDo);
...
li.appendChild(editBtn);
...
}
앞으로도 배경화면이나, 글귀들은 계속 업로드를 하겠지만,
기능적으로는 크게 달라지지 않을 것 같다.
거의 최종본!
+++ 아 아직 날씨 api 적용 안되는 거 확인을 안 했구나.. ㅎ
++ 에러보면 웹사이트 내 변경 문제인 것 같던데.. 귀찮아서.. 미루는 중이다 ㅎ
녹음 하다보니...
마지막으로 추가한 영상 버튼이..
playlist 입력 input이랑 겹치는 것을 확인해서..
저장하고,, 수정하러 가기로 ㅎㅎㅎ
증맬 끝이 없구나 ㅎ
'Projects' 카테고리의 다른 글
[Momentum_trouble shooting] 체크박스 에러가 생길 때 (0) | 2024.05.29 |
---|---|
[PLAVE-Talk] 2주간 CSS 챌린지 마무리 (0) | 2024.04.11 |
[Momentum_ problem shooting] api 숨기기 & .gitignore & gitmogi (1) | 2024.03.30 |
[Momentum_ problem shooting] LS의 유저이름 수정 버튼 만들기 (1) | 2024.03.30 |
[Momentum_ problem shooting] checkbox 가운데 선 긋기 (0) | 2024.03.30 |