TIL 01|vanillatodoコメント
81925 ワード
Project Overview
todo-list page
todo-list gitHub
ライブラリを使用せずにjavascript言語でプログラミングしたいので、2つのリストを選択しました.
勤務期間
2021.06.28 ~ 2021.07.05
テクノロジースタック
結果画面
登録保留事項
削除
保留中の事項を修正する
リストの移動
Project Review
JavaScriptはリアルタイムでレンダリングされません。
JAvascriptはreactのようにスクリーンの変化をリアルタイムでレンダリングしないため、個別にレンダリングする関数を実現する必要があります.
// render
const renderTodo = () => {
let reverse, item, join;
reverse = [...todoList];
item = reverse.filter(incomplete);
join = item.map(incompleteTemplate).join('');
INCOMPLETE.innerHTML = join;
reverse = [...completedList];
item = reverse.filter(completed);
join = item.map(completedTemplate).join('');
COMPLETED.innerHTML = join;
};
Node.insertBefore()
appendChild()
と似ているように見えますが、inrestBefore()
には2つの伝達因子があります.最初の伝達パラメータnewNodeは挿入するノードであり、2番目の伝達パラメータreferenceNodeは基点ノードである.let insertedNode = parentNode.insertBefore(newNode, referenceNode);
に感銘を与える
やるべきことを入力してEnterを押すと登録できるのですが、残念ながら最初から思っていませんでした.
文字から見ると、私はコードを書く過程であまり適切ではないコード部分を使ったので、理解が速いです.例えば、
func.bind()
、node.insertBefore()
などである.石橋も叩いたからといって、コードが完成したからといって油断しないで、再設計して研究しなければならない.
HTML Code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>vanilla todo</title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/style.css">
<script defer src="js/todo.js"></script>
</head>
<body>
<main class="todoContent">
<header>
<h1 class="title">todo list</h1>
</header>
<!-- add item -->
<section>
<h2>add item</h2>
<form class="add-form">
<div>
<label for="addInput" class="a11y-hidden">할 일 추가</label>
<input type="text" id="addInput" class="add-input" required />
<button type="submit" class="add-btn">add</button>
</div>
</form>
</section>
<!-- // add item -->
<!-- todo list -->
<section class="todo">
<h2>todo</h2>
<ul class="incomplete">
</ul>
</section>
<!-- // todo list -->
<!-- completed list -->
<section class="todo">
<h2>completed</h2>
<ul class="completed">
</ul>
</section>
<!-- completed list -->
</main>
</body>
</html>
css(rest.css) Code
@charset "utf-8";
/* margin, padding */
body,
main,
div,
span,
section,
label,
input,
form,
button,
ul,
h1,
h2,
h3,
p,
i{
margin: 0;
padding: 0;
}
/* label */
label{
background: transparent;
}
/* input */
input{
border: none;
outline:none;
background: transparent;
}
input[type="checkbox"]{
cursor: pointer;
}
/* button */
button{
border: none;
outline: none;
text-transform: capitalize;
background: transparent;
cursor: pointer;
}
/* list */
ul,
li{
list-style:none;
}
/* title */
h1,
h2,
h3{
font-weight: normal;
text-transform: uppercase;
}
i {
font-style: normal;
}
body,
input,
button,
div,
label,
span,
p,
h1,
h2,
h3,
ul,
li{
font-family: 'Roboto Condensed', sans-serif;
font-size: 1rem;
line-height: 1.5;
color: #fff;;
}
.a11y-hidden {
overflow: hidden;
position: absolute;
width: 1px;
height: 1px;
margin: -1px;
clip: rect(0 0 0 0);
clip: rect(0, 0, 0, 0);
}
css(style.css) Code
@charset "utf-8";
body {
overflow: scroll;
background:#f5f3e9 ;
}
main{
width: 28.13rem;
margin: 6.25rem auto;
padding: 1.25rem;
box-shadow: -1.25rem -1.25rem 0px 0px rgb(100 100 100 / 10%);
background: #98c0b7;
color: #fff;
}
h1{
font-size: 1.667rem;
text-align: center;
}
h2{
font-size: 1.375rem;
margin-top: 0.625rem;
border-bottom: 1px solid #fff;
}
/* add-form */
.add-form > div{
display: flex;
justify-content: space-between;
}
/* add-form input */
.add-input{
width: calc(100% - 70px);
height: 2.5rem;
margin: 0.625rem 0;
padding: 0 0.625rem;
font-size: 1.667rem;
line-height: 2.5rem;
background: #fff;
color: black;
}
/* add-form button */
.add-btn{
font-size: 1.25rem;
}
/* todo - ul li */
.todo ul li{
display: flex;
justify-content: space-between;
border-bottom: 1px solid #a2cec4;
}
/* todo - ul li checkbox */
.todo li input[type="checkbox"]{
width: 1rem;
height: 1rem;
margin: 0.8125rem 0.625rem 0 0;
line-height: 1rem;
}
/* todo -ul.incomple li label */
.todo .incomplete li label{
width: calc(100% - 165px);
margin : 0.5625rem 0;
height:1.563rem;
line-height: 1.563rem;
font-size: 1.5rem;
}
/* todo -ul.incomple li input(edit) */
.todo .incomplete li input[type="text"]{
width: calc(100% - 165px);
height: 1.563rem;
margin: 0.5rem 0;
border: 1px solid #91d4c5;
line-height: 1.563rem;
font-size: 1.5rem;
}
/* todo -ul.completed li label */
.todo .completed li label{
width: calc(100% - 85px);
height: 1.563rem;
margin: 0.5625rem 0;
line-height: 1.563rem;
font-size: 1.5rem;
}
/* todo - li butgrop buttons */
.todo-btngroup button{
padding: 0 0.625rem 0 0;
margin: 0.5rem 0.625rem 0 0;
font-size: 1.25rem;
}
/* todo - li btngroup saveBtn(edit) */
.todo-btngroup .save-btn{
padding: 0;
}
.todo-btngroup button:last-child{
padding: 0;
}
JavaScript Code
(() => {
let todoList = [];
let completedList = [];
const LOADED_TODOLIST = localStorage.getItem('TODO');
const COMPLETED_LIST = localStorage.getItem('COMPLETED');
const TODO_CONTENT = document.querySelector('.todoContent');
const ADD_INPUT = document.querySelector('.add-input');
const INCOMPLETE = document.querySelector('.incomplete');
const COMPLETED = document.querySelector('.completed');
// initialize and execute
const init = () => {
addEvent();
loadTodoList();
loadCompletedList();
renderTodo();
};
// loading todoList
const loadTodoList = () => {
if (LOADED_TODOLIST !== null) {
todoList = JSON.parse(LOADED_TODOLIST);
return todoList;
}
};
// loading compltedList
const loadCompletedList = () => {
if (COMPLETED_LIST !== null) {
completedList = JSON.parse(COMPLETED_LIST);
return completedList;
}
};
// event listener
const addEvent = () => {
let li, id, index, todo, list, checkbox, item;
let label, input, save_btn, edit_btn;
TODO_CONTENT.addEventListener('click', (e) => {
// add button
if (e.target.className === 'add-btn') {
addFormSubmit();
// delete button
} else if (e.target.className === 'delete-btn') {
li = e.target.parentNode.parentNode;
id = Number(li.getAttribute('data-id'));
checkbox = li.querySelector('input[type="checkbox"]').value;
list = checkbox === 'true' ? [...completedList] : [...todoList];
index = list.findIndex(matchingID.bind(todo, id));
list.splice(index, 1);
list = checkbox === 'true' ? (completedList = list) : (todoList = list);
renderTodo();
saveTodoList();
saveCompletedList();
// edit button
} else if (e.target.className === 'edit-btn') {
list = [...todoList];
li = e.target.parentNode.parentNode;
id = Number(li.getAttribute('data-id'));
item = todoList.find(matchingID.bind(todo, id));
label = li.querySelector('label');
label.classList.add('a11y-hidden');
save_btn = li.querySelector('.save-btn');
save_btn.classList.remove('a11y-hidden');
edit_btn = li.querySelector('.edit-btn');
edit_btn.classList.add('a11y-hidden');
input = document.createElement('input');
input.setAttribute('type', 'text');
input.setAttribute('id', id);
input.setAttribute('value', item.contents);
li.insertBefore(input, label.nextSibling);
// save button
} else if (e.target.className === 'save-btn') {
list = [...todoList];
li = e.target.parentNode.parentNode;
id = Number(li.getAttribute('data-id'));
item = list.find(matchingID.bind(todo, id));
index = list.findIndex(matchingID.bind(todo, id));
input = li.querySelector('input[type="text"]');
item.contents = input.value;
save_btn = li.querySelector('.save-btn');
save_btn.classList.add('a11y-hidden');
edit_btn = li.querySelector('.edit-btn');
edit_btn.classList.remove('a11y-hidden');
list.splice(index, 0);
todoList = list;
saveTodoList();
renderTodo();
// incomplete if checkbox value is false
} else if (e.target.type === 'checkbox' && e.target.value === 'false') {
list = [...todoList];
id = Number(e.target.id);
index = list.findIndex(matchingID.bind(todo, id));
item = list.find(matchingID.bind(todo, id));
item.isCompleted = !item.isCompleted;
completedList.push(item);
list.splice(index, 1);
todoList = list;
renderTodo();
saveTodoList();
saveCompletedList();
// complete if checkbox value is true
} else if (e.target.type === 'checkbox' && e.target.value === 'true') {
list = [...completedList];
id = Number(e.target.id);
index = list.findIndex(matchingID.bind(todo, id));
item = list.find(matchingID.bind(todo, id));
item.isCompleted = !item.isCompleted;
todoList.push(item);
list.splice(index, 1);
completedList = list;
renderTodo();
saveTodoList();
saveCompletedList();
}
});
};
// add item form validation
const addFormSubmit = () => {
let VALUE = ADD_INPUT.value;
if (VALUE === '') {
return false;
}
ADD_INPUT.value = '';
addTodoDate(VALUE);
};
// add an item to the list
const addTodoDate = (value) => {
todoList.push({
id: Math.floor(Math.random() * 999),
contents: value,
isCompleted: false,
});
renderTodo();
saveTodoList();
};
// incompleteTemplete
const incompleteTemplate = (item) => {
const INCOMPLETE_ITEM = `
<li data-id=${item.id}>
<input id=${item.id} type="checkbox" value=${item.isCompleted} />
<label for=${item.id}>${item.contents}</label>
<div class="todo-btngroup">
<button type="button" class="edit-btn">edit</button>
<button type="button" class="a11y-hidden save-btn">save</button>
<button type="button" class="delete-btn">delete</button>
</div>
</li>
`;
return INCOMPLETE_ITEM;
};
const incomplete = (item) => {
return !item.isCompleted;
};
// completed template
const completedTemplate = (item) => {
const COMPLETED_ITEM = `
<li data-id=${item.id}>
<input id=${item.id} type="checkbox" value=${item.isCompleted} />
<label for=${item.id}>${item.contents}</label>
<div class="todo-btngroup">
<button type="button" class="delete-btn">delete</button>
</div>
</li>
`;
return COMPLETED_ITEM;
};
const completed = (item) => {
return item.isCompleted;
};
// matching item
const matchingID = (id, item) => {
return item.id === id;
};
// render
const renderTodo = () => {
let reverse, item, join;
// todoList
reverse = [...todoList];
item = reverse.filter(incomplete);
join = item.map(incompleteTemplate).join('');
INCOMPLETE.innerHTML = join;
reverse = [...completedList];
item = reverse.filter(completed);
join = item.map(completedTemplate).join('');
COMPLETED.innerHTML = join;
};
// save to todoList LocalStorage
const saveTodoList = () => {
localStorage.setItem('TODO', JSON.stringify(todoList));
};
// save to completedList LocalStorage
const saveCompletedList = () => {
localStorage.setItem('COMPLETED', JSON.stringify(completedList));
};
init();
})();
Reference
この問題について(TIL 01|vanillatodoコメント), 我々は、より多くの情報をここで見つけました https://velog.io/@vi2920va/vanilla-todoテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol