Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[1주차] 김윤일 미션 제출합니다. #4

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"trailingComma": "es5",
"tabWidth": 2,
"semi": true,
"singleQuote": true
}
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"liveServer.settings.port": 5501
}
20 changes: 18 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,23 @@
</head>

<body>
<div class="container"></div>
<div class="container">
<div class="header-wrapper">
<header>📚 투두리스트</header>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

직관적인 시멘틱 태그 사용 아주 좋습니다🙌

<form class="input-box">
<input id="todo-input" type="text" placeholder="할 일을 입력하세요" />
<button id="add-todo-btn">➕</button>
</form>
</div>
<div class="body">
<h4 id="todo-list-title">📋 TO DO ()</h4>
<ul id="todo-list"></ul>
</div>
<div class="footer">
<h4 id="done-todo-list-title">💿 DONE ()</h4>
<ul id="done-todo-list"></ul>
</div>
</div>
</body>
<script src="script.js"></script>
<script src="script copy.js"></script>
</html>
117 changes: 117 additions & 0 deletions reset.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/* http://meyerweb.com/eric/tools/css/reset/
v2.0 | 20110126
License: none (public domain)
*/

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

우와 이런 것까지 적용해 보셨군요 👍🏻👍🏻
reset.css는 말 그대로 기본 스타일을 모두 초기화해 버려서 일일이 새로 지정하기 번거로울 수 있어요! 비슷하게 normalize.css라는 게 있는데, 이건 브라우저마다 상이한 부분만 스타일을 통일시켜 주는 역할을 합니다 🙂 이것도 알아보시면 좋을 것 같아요 🙌

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이런 게 있다는 걸 윤일님 덕분에 처음 알고 갑니다..🫢 기본적으로 적용된 마진 때문에 고민이 많았는데 이런 방법이 있었다니..!!
참고해서 다음 과제부터 적용해보겠습니다🥰🥰

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

맞아요! 모두 초기화하는 reset.css보단 부분적으로 초기화해주는 normalize.css가 편리한 거 같아요! 다음 과제에 바로 적용해보려구요👍🏻👍🏻👍🏻

html,
body,
div,
span,
applet,
object,
iframe,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
strong,
sub,
sup,
tt,
var,
b,
u,
i,
center,
dl,
dt,
dd,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
hgroup,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
display: block;
}
body {
line-height: 1;
}

blockquote,
q {
quotes: none;
}
blockquote:before,
blockquote:after,
q:before,
q:after {
content: '';
content: none;
}
Comment on lines +107 to +113
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blockquote와 q를 :before, :after 요소를 적용해서 이와 같이 스타일링한 이유가 궁금해요!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reset.css는 제가 초기화한게 아닌 양식입니다! 제가 사용한 양식 사이트 올려드릴게요.

사용하면서 느낀 점은 모든 것을 다 초기화 해주기 때문에 <h1>태그 같은 경우에는 폰트나 굵기가 다 사라져서 태그를 사용하는 의미가 사라진다고 느꼈습니다. 그래서 위 코드에서는 h태그 관련 초기화를 삭제하고 사용했습니다. 이러한 점들 때문에 위에서 주현님께서 추천해주신 normalize.css를 사용해보려고 합니다! 여은님도 한번 사용해보시면 좋을 거 같아요👍🏻👍🏻👍🏻

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오! 이런게 있는지 몰랐어요! 기본 태그에서 필요없는 속성을 한번에 제거할 수 있어서 너무 편하네요😀 또 새롭게 알아갑니당

table {
border-collapse: collapse;
border-spacing: 0;
}
78 changes: 77 additions & 1 deletion script.js
Original file line number Diff line number Diff line change
@@ -1 +1,77 @@
// 다들 화이팅!! ٩( *˙0˙*)۶
const todoInput = document.getElementById('todo-input'); // 할 일 입력창
const todoList = document.getElementById('todo-list'); // 할 일 리스트창
const addTodoBtn = document.getElementById('add-todo-btn'); // 버튼
const doneTodoList = document.getElementById('done-todo-list'); // 완료된 할 일 리스트창
const todoListTitle = document.getElementById('todo-list-title'); // 할 일 제목
const doneTodoListTitle = document.getElementById('done-todo-list-title'); // 완료된 할 일 제목

// input으로 입력 받은 할 일을 리스트창에 추가
function addTodo(event) {
event.preventDefault(); // form 태그의 기본 새로고침 기능 지우기
Comment on lines +8 to +10
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

주석 굿굿!


const $li = document.createElement('li');
const $btn = document.createElement('button');

const todoText = todoInput.value.trim();

//공백 방지
if (!todoText) {
alert('공백은 입력할 수 없습니다.');
}
Comment on lines +18 to +20
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

공백 입력 방지를 알리는 부분 좋아요! 추가로 return 문을 넣는다면 공백 입력된 li 태그가 생성되는 것을 완전히 막을 수 있을 것 같습니다!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return으로 공백 방지 조건 후 함수를 종료하면 다른 경우 없이 막을 수 있겠네요!! 정확한 피드백 감사합니다😊

Comment on lines +18 to +20
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

윤일님도 truthy로 조건문을 구성하셨네요! '==='을 사용하는 것보다 훨씬 깔끔한 것 같아요


$li.innerText = todoText;
todoList.appendChild($li);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

append()appendChild()의 차이를 아시나요?!
둘 다 비슷한 기능을 해서 해당 코드에서는 크게 상관은 없지만, 이번 기회에 알아보는 것도 좋을 것 같습니다 🙂
참고자료 - append와 appendChild

todoInput.value = ''; // 입력 필드 초기화
todoInput.focus(); // 입력 필드로 커서 이동
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 사용자의 편의성을 고려한 코드 아주 좋아요👍


$li.appendChild($btn);
$btn.innerText = '❌';

// 삭제 버튼 클릭 시 해당 li 삭제
$btn.addEventListener('click', (e) => {
e.stopPropagation(); // 이벤트 전파 막기 -> li태그의 자식요소로 삭제버튼이 있기 때문에 버튼을 눌러도 완료항목으로 이동하는 문제발생
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오옹 e.preventDefault()에 대해서만 알고 있었는데, 부모 엘리먼트에 이벤트 전파를 막는 e.stopPropagation()는 처음 알았네요! 좋은 지식 얻고갑니다👍🏻👍🏻

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네 맞습니다!! 다른 방법으로는 HTML태그를 세분화해서 특정 태그에만 클릭이벤트를 적용하면 e.stopPropagation()을 사용 하지 않아도 된다는 사실까지 알아두시면 좋을 거 같아요🥰

removeTodo(li, true);
});
todoFlagCount(true);

$li.addEventListener('click', () => doneTodo($li));
}

addTodoBtn.addEventListener('click', addTodo);

// 완료
function doneTodo(liItem) {
let doneLi = document.createElement('li');
let doneBtn = document.createElement('button');

doneLi.innerText = liItem.innerText.replace('❌', ''); // *텍스트만 가져오기*
doneTodoList.appendChild(doneLi);

doneBtn.innerText = '❌';
doneLi.appendChild(doneBtn);

doneBtn.addEventListener('click', () => {
removeTodo(doneLi, false);
});
// 원래 todo 목록에서 삭제
liItem.remove();
todoFlagCount(true);
todoFlagCount(false);
}

// 할 일 삭제
function removeTodo(liItem, isTodo) {
liItem.remove();
todoFlagCount(isTodo);
}

// 할 일 개수 업데이트
function todoFlagCount(isTodo) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(개인적인 의견입니다)

할 일 개수를 카운팅 하는 함수를 따로 빼고 중복을 줄인 점 아주 좋습니다!! 다만, 해당 함수를 사용할 때 todoFlagCount(true) 형식으로 사용하게 되는데, 이러면 '투두 플래그(?)를 카운팅 하겠다', '투두 플래그(?)를 카운팅 하지 않겠다'라고 생각할 것 같아요. 그러면 결국 todoFlagCount가 뭐지? 하면서 해당 함수를 찾아보게 되고, 다시 읽어 보면서 그 의미를 파악하는 데 시간이 걸릴 것 같습니다 🥵

말이 길어지긴 했는데, 결국은 함수명이 조금 모호한 것 같다는 생각입니다! 그래서 차라리 아래처럼 todoFlagCount 함수의 인자를 객체 형태로 받으면 key와 value를 명시하면서 어떠한 값이 true일 때를 나타내는지 알기 쉬울 것 같아요!

Suggested change
function todoFlagCount(isTodo) {
function todoFlagCount({ isTodo }) { ... }
todoFlagCount({ isTodo: true });
todoFlagCount({ isTodo: false });

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그리고 이건 다른 말이긴 하지만,, 제가 투두리스트를 만들었을 때에는 할일/완료한일 목록을 각각 배열에 저장하여 관리했습니다! 그러면 할일 개수를 셀 때 배열의 length 값을 사용하면 되니까 편하더라구요!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 배열에 저장하면 개수를 셀 때나 가져올 때가 편하겠군요! react로 할 때 반영해보겠습니다!
함수의 기능을 나누면서 이게 맞는걸까.. 고민했는데 알려주신대로 함수의 인자를 객체 형태로 받으면 가독성이 더 좋아질 거 같습니다!
감사합니다☺️

if (isTodo) {
let count = todoList.getElementsByTagName('li').length;
todoListTitle.innerText = `📋 TO DO (${count})`;
} else {
let count = doneTodoList.getElementsByTagName('li').length;
doneTodoListTitle.innerText = `💿 DONE (${count})`;
}
}
95 changes: 94 additions & 1 deletion style.css
Original file line number Diff line number Diff line change
@@ -1 +1,94 @@
/* 자유롭게 디자인 해 주세요! */
@import './reset.css';

* {
font-family: 'SpoqaHanSansNeo-Regular';
}
html,
body {
margin: 0;
}
body {
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: radial-gradient(#e66465, #9198e5);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

그라데이션 예쁘네욤

}
.container {
display: flex;
flex-direction: column;
width: 360px;
height: 600px;
border-radius: 20px;
background-color: white;
box-shadow: 0 0 25px rgba(0, 0, 0, 0.25);
}
.header-wrapper {
flex-direction: row;
}
header {
margin: 5% 5% 0;
font-size: 24px;
}
.input-box {
display: flex;
align-items: center;
justify-content: center;
border-bottom: 1px solid lightgray;
padding: 5%;
}
#todo-input {
width: 80%;
height: 60%;
margin: 1%;
padding: 5%;
border: 0.5px solid gray;
border-radius: 15px;
}
#add-todo-btn {
height: 60%;
margin: 1%;
border: 0px;
background-color: transparent;
cursor: pointer;
}
.body {
height: 40%;
display: flex;
flex-direction: column;
border-bottom: 1px solid lightgray;
}
#todo-list-title {
margin: 18px;
}
.footer {
height: 40%;
display: flex;
flex-direction: column;
}
#done-todo-list-title {
margin: 18px;
}

ul {
height: 70%;
overflow: auto;

padding-left: 40px;
}

li {
margin: 0 16px 16px;
}

#done-todo-list:nth-child(2) {
color: lightgray;
text-decoration: line-through;
}

li > button {
margin-left: 10px;
background: transparent;
border: 0px;
}