Last active
May 9, 2020 12:50
-
-
Save zaru/2d7b3c456ac5475eb92ff687b4415cd1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" | |
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | |
<title>Document</title> | |
<style type="text/css"> | |
.todo-done { | |
text-decoration: line-through; | |
} | |
</style> | |
</head> | |
<body> | |
<ul id="todo-list"></ul> | |
<template id="todo-template"> | |
<li><span></span><button>done</button></li> | |
</template> | |
<input type="text" name="new-todo"><button id="add-todo">add</button> | |
<script> | |
function done(node) { | |
// 打ち消し線の CSS を適用して完了したように見せる | |
const parent = node.target.closest('li'); | |
parent.classList.add('todo-done'); | |
// 完了済みにデータを更新する | |
const id = parent.id.replace('todo-', ''); | |
updateById(id, { done: true }); | |
} | |
function add() { | |
// 入力フォームから、入力したテキストを取得 | |
const input = document.querySelector('input[name="new-todo"]'); | |
const text = input.value; | |
// 入力フォームのテキストはもう必要ないので空にする | |
input.value = ''; | |
// ToDo のデータを作成する | |
const data = build(text); | |
// ToDo を表示する | |
show(data); | |
// LocalStorage に保存する | |
save(data); | |
} | |
function show(data) { | |
// テンプレートを読み込む | |
const template = document.querySelector('#todo-template'); | |
const todoList = document.querySelector('#todo-list'); | |
// テンプレートから、新しい ToDo を作成する(テキスト設定と done ボタンのイベント設定) | |
const clone = document.importNode(template.content, true); | |
clone.querySelector('li').id = `todo-${data.id}`; | |
clone.querySelector('span').textContent = data.todo; | |
clone.querySelector('button').addEventListener('click', done); | |
// もし完了の場合は、完了スタイルのクラスを追加する | |
if (data.done) { | |
clone.querySelector('li').classList.add('todo-done'); | |
} | |
// 実際に表示させる | |
todoList.appendChild(clone); | |
} | |
// ToDo のデータを生成する | |
function build(text) { | |
const todo = getAllTodoList(); | |
return { | |
id: getLatestID(todo), | |
todo: text, | |
done: false | |
} | |
} | |
// 最新の ID を取得する | |
function getLatestID(data) { | |
if (data.length > 0) { | |
return Math.max(...data.map(v => v.id)) + 1; | |
} | |
return 1; | |
} | |
// 渡された ToDo のデータを保存する | |
function save(data) { | |
const todoList = getAllTodoList(); | |
todoList.push(data); | |
localStorage.setItem('todo', JSON.stringify(todoList)); | |
} | |
// 指定された ID の ToDo のデータを更新する | |
function updateById(id, data) { | |
const todoList = getAllTodoList(); | |
const index = todoList.findIndex(v => v.id === parseInt(id)); | |
if (index) { | |
for (let [key, value] of Object.entries(data)) { | |
todoList[index][key] = value; | |
} | |
//TODO: 例外処理 | |
localStorage.setItem('todo', JSON.stringify(todoList)); | |
} | |
} | |
// 保存されている全ての ToDo を取得する | |
function getAllTodoList() { | |
const todoList = localStorage.getItem('todo'); | |
//TODO: 例外処理 | |
return todoList ? JSON.parse(todoList) : []; | |
} | |
// 全ての ToDo を表示する | |
function showAllTodoList() { | |
const todoList = getAllTodoList(); | |
todoList.forEach(data => show(data)); | |
} | |
// add ボタンのイベント設定 | |
const addTodoButton = document.getElementById('add-todo'); | |
addTodoButton.addEventListener('click', add); | |
showAllTodoList(); | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" | |
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | |
<title>Document</title> | |
<style type="text/css"> | |
.todo-done { | |
text-decoration: line-through; | |
} | |
</style> | |
</head> | |
<body> | |
<ul id="todo"></ul> | |
<template id="todo-template"> | |
<li><span></span><button>done</button></li> | |
</template> | |
<input type="text" name="new-todo"><button id="add-todo">add</button> | |
<script> | |
function done(node) { | |
// 打ち消し線の CSS を適用して完了したように見せる | |
node.target.closest('li').classList.add('todo-done'); | |
} | |
function add() { | |
// 入力フォームから、入力したテキストを取得 | |
const input = document.querySelector('input[name="new-todo"]'); | |
const text = input.value; | |
// 入力フォームのテキストはもう必要ないので空にする | |
input.value = ''; | |
// テンプレートを読み込む | |
const template = document.querySelector('#todo-template'); | |
const todo = document.querySelector('#todo'); | |
// テンプレートから、新しい ToDo を作成する(テキスト設定と done ボタンのイベント設定) | |
const clone = document.importNode(template.content, true); | |
clone.querySelector('span').textContent = text; | |
clone.querySelector('button').addEventListener('click', done); | |
// 実際に表示させる | |
todo.appendChild(clone); | |
} | |
// add ボタンのイベント設定 | |
const addTodoButton = document.getElementById('add-todo'); | |
addTodoButton.addEventListener('click', add); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment