๋ณธ ํฌ์คํ ์ javascript์ ์ ๋ฌธํ๊ณ ์ ํ๋ ค๊ณ ํ ๋ ๊ฐ๋ณ๊ฒ ํ์ต ํ ์ ์๋๋ก ๋๋ฆ์ ์ปค๋ฆฌํ๋ผ์ ์ง๋ณธ ๊ฒ์ ๋๋ค.
todo-list ํ๋ก์ ํธ๋ ๋ค๋ฅธ ๊ฒ์๊ธ์ด๋ ์ ํฌ๋ธ์๋ ๋ง์ด ๋์์๊ธฐ๋ ํ์ง๋ง, ์ด๋ณด์๊ฐ ์ข ๋ ์ ๊ทผํ๊ธฐ ์ฝ๋๋ก ์์ฐจ์ ์ผ๋ก ์งํ ๊ณผ์ ์ ์ชผ๊ฐ ๋ณด์์ต๋๋ค.
์์
1. ๊ธ ์ถ๊ฐํ๊ธฐ
2. ๊ธ ์ญ์ ํ๊ธฐ
3. ๊ธ ์์ ํ๊ธฐ
4. localStorage์ ์ ์ฅํ๊ธฐ
* html๊ณผ css๋ ๋์ถฉ ๋ง๋ค์ด ๋์์ต๋๋ค. (์ ๋ง ๋์ถฉ ใ ..)
์ด ์์ค๋ฅผ ๋ค์ด๋ฐ์ ์์ํ๋ฉด ๋ฉ๋๋ค.
๊ธฐ๋ฅ ๋ชฉ๋ก์ ์ฐธ์กฐํ์ฌ ๋ฏธ๋ฆฌ ์์ค๋ฅผ ๋ง๋ค์ด๋ณธ ๋ค, ์์ฑ๋ ์์ค์ ๋น๊ตํด ๋ณด์ธ์!
1. ๊ธ ์ถ๊ฐํ๊ธฐ
๊ตฌํํ ๊ธฐ๋ฅ ๋ชฉ๋ก
- input ์
๋ ฅ ํ "ADD" ๋ฒํผ ๋๋ฅด๋ฉด ํ๋จ์ ์ถ๊ฐ
- input ์ด ๋น๊ฐ์ธ ๊ฒฝ์ฐ "ADD" ๋ฒํผ ํด๋ฆญ์ "๊ฐ์ ์
๋ ฅํ์ธ์!" alert์ ๋์ด ํ input์ผ๋ก focus
- ๋ชฉ๋ก์ ์๋ฌด๊ฒ๋ ์์๋๋ "๋ฐ์ดํฐ๊ฐ ์์ต๋๋ค" ์ถ๋ ฅ
โถ ์์ค๋ณด๊ธฐ
์ฐ์ html ๋ด์ todo_item์ ๋์ด์ ํ์๊ฐ ์์ผ๋ ์ฃผ์ ์ฒ๋ฆฌ ํ๊ฑฐ๋, ์ญ์ ํด ์ฃผ์ธ์.
javascript ์์ ์์์ render๋ฅผ ํ ๊ฒ์ ๋๋ค.
// index.html
<div class="wrapper">
<div class="form">
<input type="text" class="todo_input">
<button class="btn_add">ADD</button>
<button class="btn_clear">CLEAR</button>
</div>
<div class="todo_list_wrap">
<ul class="todo_list">
<!-- ํธ์ง๊ธฐ๋ฅ ํ์ฑํ : todo_item + edit_wrap -->
<!-- <li class="todo_item ">
<div class="edit_wrap">
<input type="text" class="edit_input" />
<button class="button btn_edit">EDIT</button>
</div>
<p class="text">
Hello world!
</p>
<button class="button btn_amend">Amend</button>
<button class="button btn_delete">Delete</button>
</li> -->
</ul>
</div>
</div>
์ฐ์ ์ํ๋ฅผ ๊ด๋ฆฌํ ๋ฐฐ์ด์ ํ๋ ์์ฑํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ํ์ํ ๋ณ์๋ฅผ ์ ์ธํฉ๋๋ค.
let listArray = []; // ํ ์ผ์ด ๋ด๊ธธ ๋ฐฐ์ด
const todoList = document.querySelector('.todo_list'); // ๋ฐฐ์ด์ ๋ชฉ๋ก์ ๋ฟ๋ ค์ค ๋ถ๋ชจ
const todoInput = document.querySelector('.todo_input'); // ํ ์ผ์ ๋ด์ฉ์ ์
๋ ฅํ๋ input
const btnAdd = document.querySelector('.btn_add'); // ์
๋ ฅ ์๋ฃํ ์ถ๊ฐ๋ฅผ ํ๊ธฐ์ํ ๋ฒํผ
๊ทธ๋ฆฌ๊ณ ํจ์ ๋ ๊ฐ๋ฅผ ๋ง๋ค์ด์ค ํ ๋ฐ ํ๋๋ ์ค์ ์ถ๊ฐ ๋ฒํผ์ ๋๋ ์๋ ์ถ๊ฐ๊ฐ ์ด๋ฃจ์ด์ง๋ ํจ์์ด๊ณ , ๋ค๋ฅธ ํ๋๋ ๋ฐฐ์ด์ ๋ฌด์ธ๊ฐ๊ฐ ์ถ๊ฐ๋์์๋ html์ ๋ฟ๋ ค์ฃผ๋ ํจ์์ ๋๋ค.
// add list
const addTodo = () => {
// ํ ์ผ์ listArray ๋ฐฐ์ด์ ์ถ๊ฐํฉ๋๋ค.
}
// show list
const showList = () => {
// html์ ๋ฟ๋ ค์ค๋๋ค.
}
btnAdd.addEventListener('click', addTodo);
addTodo ์์ ๋ง์ฝ input์ value ๊ฐ์ด ๋น์ด์๋ค๋ฉด alert์ ๋์์ค ํ input์ผ๋ก ๋ค์ focusํด์ค๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ค์๋์์ด ํ์ง ์๊ธฐ ์ํด์ return false๋ฅผ ํด์ค๋๋ค.
๋ง์ฝ ๋น์ด์์ง ์๋ค๋ฉด, listArray์ ํด๋น value๊ฐ์ pushํ์ฌ ์ถ๊ฐํด ์ค ๋ค,
input์ value๊ฐ์ ๋น๊ฐ์ผ๋ก ์ด๊ธฐํ ํด์ค๋๋ค.
์ฐ์ ์ ํ๋ฉด์ ๊ทธ๋ฆฌ๋ ํจ์๋ ์์ง ์ ์๊ฐ ์๋์์ผ๋ฏ๋ก, console๋ก ๋ฐฐ์ด์ ์ฐ์ด์ ํ์ธํด ๋ด ์๋ค.
const addTodo = () => {
const inputValue = todoInput.value; // input์ value๊ฐ์ ๊ฐ์ ธ์ต๋๋ค
if(inputValue === "") { // input ์ value ๊ฐ์ด ๋น์ด์๋ค๋ฉด
alert("๊ฐ์ ์
๋ ฅํ์ธ์!"); // alert์ ๋์ฐ๊ณ
todoInput.focus(); // input์ ๋ค์ focus๋ฅผ ์์ผ์ค๋๋ค.
return false; // ๋ค์ ๋์์ ๋ฉ์ถฅ๋๋ค.
}
// ๋ง์ฝ value๊ฐ์ด ์๋ค๋ฉด
listArray.push(inputValue); // listArray์ value๊ฐ์ ์ถ๊ฐํด ์ค๋๋ค.
// ๊ทธ๋ฆฌ๊ณ input์ ๊ฐ์ ๋น์์ค๋๋ค. ๋ง์ฝ ํด์ฃผ์ง ์์ผ๋ฉด ์ ์ ์
๋ ฅํ ๊ฐ์ด ๊ทธ๋๋ก ๋จ์์๊ฒ ๋ฉ๋๋ค.
todoInput.value = "";
console.log(listArray) // ์ ์ถ๊ฐ๊ฐ ๋์๋์ง ํ์ธํด๋ด
๋๋ค!
}
์์ฃผ ์ ๋๋ค์. ๊ทธ๋ฌ๋ฉด ์ค์ ๋ก html์ ๊ทธ๋ ค์ค๋๋ค. ์ ์ ์ฃผ์ํด๋์๋ todo_item ์ ๊ทธ๋๋ ๊ทธ๋ ค์ค ๊ฑด๋ฐ, ํ ์คํธ ๋์ ๋ฐ์ดํฐ๋ฅผ ์ฐ๊ฒฐํด ์ค ๊ฒ์ ๋๋ค. listArray์ length๊ฐ์ ์ฒดํฌํ์ฌ 0 ์ธ๊ฒฝ์ฐ๋ ๋ฐ์ดํฐ๊ฐ ์์ง ํ ์ผ ๋ชฉ๋ก์ด ์๋ฌด๊ฒ๋ ์๋ค๋ ๋ป์ด๋ "๋ฐ์ดํฐ๊ฐ ์์ต๋๋ค"๋ฅผ ์ถ๋ ฅํด ์ฃผ๊ณ , 1๊ฐ ์ด์์ธ ๊ฒฝ์ฐ ๋ฐ์ดํฐ๋ฅผ ๊ทธ๋ ค์ค๋๋ค.
// show list
const showList = () => {
if(listArray.length > 0) { // ๋ฐ์ดํฐ๊ฐ 0๊ฐ ์ด์์ธ ๊ฒฝ์ฐ ์ฆ, ๋ฐ์ดํฐ๊ฐ ์๋ ๊ฒฝ์ฐ
todoList.innerHTML = ""; // ์ฐ์ ๊ธฐ์กด ๋ฐ์ดํฐ๋ฅผ ๋ชจ๋ ์ญ์ ํ์ฌ ์ด๊ธฐํ ์์ผ์ค๋๋ค.
listArray.forEach(function(text, idx){ // ๊ทธ๋ฆฌ๊ณ forEach๋ฅผ ํตํ์ฌ ๋ฐฐ์ด์ ๊ฐ์๋งํผ ๊ทธ๋ฆฝ๋๋ค.
const itemTag = '<li class="todo_item ">' +
'<div class="edit_wrap">' +
'<input type="text" class="edit_input" value="'+text+'" />' +
'<button class="button btn_edit" onClick="amendTodo('+idx+')">EDIT</button>' +
'</div>' +
'<p class="text">'+ text +'</p>' +
'<button class="button btn_amend" onClick="activeEdit('+idx+')">Amend</button>' +
'<button class="button btn_delete" onClick="deleteTodo('+idx+')">Delete</button>' +
'</li>'
todoList.innerHTML += itemTag // innerHTML๋ก ํ๋์ฉ ์ถ๊ฐํ์ฌ ๊ทธ๋ฆฝ๋๋ค.
});
} else { // ๋ฐ์ดํฐ๊ฐ ์๋ ๊ฒฝ์ฐ
todoList.innerHTML = "<li>๋ฐ์ดํฐ๊ฐ ์์ต๋๋ค</li>";
}
}
์ด๋ ๊ฒ ํ ๋ค ์ถ๊ฐํ ๋์๋ console ๋์ showList ํจ์๋ฅผ ๋ถ๋ฌ์ค๋ฉด ๋ฉ๋๋ค.
* ์ต์ข ์์ค
let listArray = [];
const todoList = document.querySelector('.todo_list');
const todoInput = document.querySelector('.todo_input');
const btnAdd = document.querySelector('.btn_add');
// add list
const addTodo = () => {
const inputValue = todoInput.value;
if(inputValue === "") {
alert("๊ฐ์ ์
๋ ฅํ์ธ์!");
todoInput.focus();
return false;
}
listArray.push(inputValue);
todoInput.value = "";
showList()
}
// show list
const showList = () => {
if(listArray.length > 0) {
todoList.innerHTML = "";
listArray.forEach(function(text, idx){
const itemTag = '<li class="todo_item ">' +
'<div class="edit_wrap">' +
'<input type="text" class="edit_input" value="'+text+'" />' +
'<button class="button btn_edit" onClick="amendTodo('+idx+')">EDIT</button>' +
'</div>' +
'<p class="text">'+ text +'</p>' +
'<button class="button btn_amend" onClick="activeEdit('+idx+')">Amend</button>' +
'<button class="button btn_delete" onClick="deleteTodo('+idx+')">Delete</button>' +
'</li>'
todoList.innerHTML += itemTag
});
} else {
todoList.innerHTML = "<li>๋ฐ์ดํฐ๊ฐ ์์ต๋๋ค</li>";
}
}
btnAdd.addEventListener('click', addTodo);
showList()
2. ๊ธ ์ญ์ ํ๊ธฐ
๊ธฐ๋ฅ๋ชฉ๋ก
- "Delete" ๋ฒํผ ํด๋ฆญ ์ ํด๋น ์์ดํ
์ญ์
- "CLEAR" ๋ฒํผ ํด๋ฆญ ์ ๋ชจ๋ ์์ดํ
์ญ์
โถ ์์ค๋ณด๊ธฐ
๊ธ ์ญ์ ํ๊ธฐ๋ ์ด๋ฏธ ๋ฟ๋ ค์ฃผ๋ ๊ธฐ๋ฅ์ด ๋ง๋ค์ด์ ธ ์๊ธฐ๋๋ฌธ์ ์ข ๋ ๊ฐ๋จํฉ๋๋ค.
ํด๋ฆญํ์๋ ์ญ์ ํ๋ ๊ธฐ๋ฅ, ํด๋ฆญ ํ์๋ ์ ๋ถ ์ญ์ ํ๋ ๊ธฐ๋ฅ 2๊ฐ์ง๋ง ์ถ๊ฐํด ์ฃผ๋ฉด๋ฉ๋๋ค.
์ด ๋ง์, ํ๋๋ง ์ญ์ ํ๋ ๊ฒฝ์ฐ ๋ฐฐ์ด์์ ํด๋น ๊ธ๋ง ๋ฐฐ์ด์์ ์ญ์ ํ๊ณ , ๋ชจ๋ ์ญ์ ํ๋ ๊ฒฝ์ฐ ๋ฐฐ์ด์ ์ด๊ธฐํ ์์ผ์ฃผ๋ฉด ๋ฉ๋๋ค.
ํด๋น ๊ธ์ ์ฐพ๊ธฐ์ํด์ id๊ฐ ํ์ํ๋ฐ, ์ฌ๊ธฐ์๋ ๊ฐ๋จํ๊ฒ index๊ฐ์ ์ฌ์ฉํ์์ต๋๋ค.
ํ ๊ฐ์ ๊ธ๋ง ์๋ผ๋ด๊ธฐ ์ํด splice ํจ์๋ฅผ ์ฌ์ฉํ์์ต๋๋ค.
splice(num1, num2) ์ num1 ๋ฒ์งธ (0๋ฒ๋ถํฐ ์์ํด์ ์ธ์ด์ผ ํฉ๋๋ค) ๋ถํฐ num2 ๋งํผ ์๋ผ๋ด๊ฒ ๋ค๋ ๋ป์ ๋๋ค.
var list = [1, 2, 3, 4, 5]
console.log(list.splice(2, 2)) // ์๋ ค๋๊ฐ ๊ฐ [3, 4]
console.log(list) // splice ์ดํ list ์ ๊ฐ [1, 2, 5]
* ์ต์ข ์์ค
{...}
const btnClear = document.querySelector('.btn_clear'); // ์ด๊ธฐํ ๋ฒํผ์ ๊ฐ์ ธ์ต๋๋ค.
{ ... }
// delete todo - ํ๋๋ง ์ญ์
const deleteTodo = (idx) => {
listArray.splice(idx, 1); // ๋ฐฐ์ด์ค idx ๋ฒ์งธ 1๊ฐ๋ฅผ ์๋ผ ๋ด๊ฒ ๋ค๋ ๋ป์
๋๋ค.
showList() // ๊ทธ๋ฆฌ๊ณ ๋ฐ๋ ๊ฐ์ด ๋ค์ ๊ทธ๋ ค์ง ์ ์๋๋ก showList๋ฅผ ํธ์ถ ํฉ๋๋ค.
}
// clear All - ๋ชจ๋ ์ญ์
const clearAll = () => {
listArray = []; // ๋ฐฐ์ด์ ์ด๊ธฐํ ์ํจ ๋ค
showList(); // ๋ฐ๋ ๊ฐ์ด ๋ค์ ๊ทธ๋ ค์ง ์ ์๋๋ก showList๋ฅผ ํธ์ถ ํฉ๋๋ค.
}
// show list
const showList = () => {
// btn_delete ๋ฒํผ ๋ถ๋ถ์ onClick ํจ์๋ฅผ ์ถ๊ฐํฉ๋๋ค. idx๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ๋๊ฒจ์ค๋๋ค.
{...}
'<button class="button btn_delete" onClick="deleteTodo('+idx+')">Delete</button>' +
{...}
});
} else {
todoList.innerHTML = "<li>๋ฐ์ดํฐ๊ฐ ์์ต๋๋ค</li>";
}
}
btnAdd.addEventListener('click', addTodo);
btnClear.addEventListener('click', clearAll);
showList()
3. ๊ธ ์์ ํ๊ธฐ
๊ธฐ๋ฅ๋ชฉ๋ก
- "Amend" ๋ฒํผ ํด๋ฆญ ์ edit ํ๋ฉด ์ถ๋ ฅ ๋ฐ edit input์ ๊ธฐ์กด ๊ฐ ์ถ๋ ฅ
- edit input์ด ๋น๊ฐ์ธ ๊ฒฝ์ฐ "edit"๋ฒํผ ํด๋ฆญ์ "๊ฐ์ ์
๋ ฅํ์ธ์!" alert์ ๋์ดํ input์ผ๋ก focus
โถ ์์ค๋ณด๊ธฐ
์ค์ ์์ ์ด ์ ์ฅ ๋๋ ์ญํ์ ์ํ ํ๋ ๊ฒ์ btn_edit ์ ๋๋ค. ์ฌ๊ธฐ์ amendTodoํจ์๋ฅผ ์ถ๊ฐํ๊ณ idx๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ๋๊น๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ง์ฐฌ๊ฐ์ง๋ก splice๋ฅผ ํตํ์ฌ ๊ฐ์ ์์ ํฉ๋๋ค. ์ด๋ฒ์๋ 3๊ฐ์ ์ธ์๋ฅผ ๋ฐ๋๋ฐ ๋ง์ฐฌ๊ฐ์ง๋ก (num1, num2, num3) ์ด ์์๋ num1๋ฒ์งธ์ ๊ฐ num2๋งํผ ์ญ์ ํ๊ณ , num3์ ์ถ๊ฐํ๊ฒ ๋ค๋ ๋ป์ ๋๋ค.
var list = [1, 2, 3, 4, 5]
console.log(list.splice(1, 2, 3)) // 1๋ฒ์งธ ๋๊ฐ์ ๊ฐ์ ์ญ์ ํ๊ณ 3์ ๋ฃ๊ฒ ๋ค๋ ๋ป์
๋๋ค.
console.log(list)
// ๊ฒฐ๊ณผ
[2, 3]
[1, 3, 4, 5]
๊ทธ๋ฆฌ๊ณ ๋ง์ฐฌ๊ฐ์ง๋ก ํธ์งํ๋ฉด์ input์ธ edit_input์๋ ๋น๊ฐ ์ฒ๋ฆฌ๋ฅผ ํด์ฃผ๋ฉด ๋ฉ๋๋ค.
* ์ต์ข ์์ค
{...}
// edit_wrap active : ํธ์ง ํ์
ํ์ฑํ
const activeEdit = (idx) => {
const items = document.querySelectorAll('.todo_item');
const item = items[idx];
item.classList.add('edit_active');
}
// ์ค์ ์์ ํ๋ ํจ์
const amendTodo = (idx) => {
const items = document.querySelectorAll('.todo_item');
const item = items[idx];
const newInput = item.querySelector('.edit_input');
const newValue = newInput.value;
if(newValue === "") { // ๋น๊ฐ์ธ ๊ฒฝ์ฐ ์ฒดํฌ!
alert("๊ฐ์ ์
๋ ฅํ์ธ์");
newInput.focus();
} else {
listArray.splice(idx, 1, newValue); // idx๋ฒ์งธ 1๊ฐ์ ๊ฐ์ newValue๋ก ๊ต์ฒด
item.classList.remove('edit_active'); // ๊ทธ๋ฆฌ๊ณ ์๋์ผ๋ก edit ํ๋ฉด์ ์ข
๋ฃํฉ๋๋ค.
showList(); // ๋ค์ ๊ทธ๋ ค์ฃผ๋ฉด ์์ ๋ ๋ด์ญ์ด ๋ฐ์๋ฉ๋๋ค!
}
}
// show list
const showList = () => {
if(listArray.length > 0) {
todoList.innerHTML = "";
listArray.forEach(function(text, idx){
const itemTag = '<li class="todo_item ">' +
'<div class="edit_wrap">' +
'<input type="text" class="edit_input" value="'+text+'" />' +
'<button class="button btn_edit" onClick="amendTodo('+idx+')">EDIT</button>' +
'</div>' +
'<p class="text">'+ text +'</p>' +
'<button class="button btn_amend" onClick="activeEdit('+idx+')">Amend</button>' +
'<button class="button btn_delete" onClick="deleteTodo('+idx+')">Delete</button>' +
'</li>'
todoList.innerHTML += itemTag
});
} else {
todoList.innerHTML = "<li>๋ฐ์ดํฐ๊ฐ ์์ต๋๋ค</li>";
}
}
btnAdd.addEventListener('click', addTodo);
btnClear.addEventListener('click', clearAll);
showList()
์ด๋ ๊ฒ ํ๋ฉด ๋ฐฐ์ด๋ก ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ ์ ์๋ Vanila JavaScript ๋ก ๋ง๋ ์์ค๊ฐ ์์ฑ ๋์์ต๋๋ค. ๐
'๊ฐ๋ฐ ๐พ > JavaScript' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๋ ์์ ์ด์ธ์ ํด๋ฆญ ํ๋ฉด .. ! (feat. ์ ๋ ํธ ๋ฐ์ค ์ปค์คํ ์ฐ์ฅ์ ) (8) | 2021.10.22 |
---|---|
๋ฆฌ์คํธ์ ์ ๋๋ฉ์ด์ ํจ๊ณผ์ฃผ๊ธฐ (0) | 2019.11.21 |
๋๋ค์ซ์๋ง๋ค๊ธฐ๊ฒ์ (0) | 2019.11.20 |
์๋์ผ๋ก ์์๋๋ก ์ซ์๊ฐ ๋ฃ์ด์ฃผ๊ธฐ - CSS counter (0) | 2019.11.12 |