以下はTODOアプリの実装例です。evalやサイト遷移、リダイレクトなどは使用していません。また、JavaScriptのオブジェクトでTODOリストを管理しています。
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>TODOアプリ</title>
<style>
/* スタイルを適用する */
body{
font-size: 16px;
line-height: 1.6em;
font-family: Arial, sans-serif;
color: #333;
padding: 20px;
}
h1, h2 {
margin-top: 0;
}
ul {
list-style: none;
padding: 0;
}
li {
margin-bottom: 10px;
padding: 10px;
border: 1px solid #ccc;
}
.btn {
padding: 5px 10px;
background-color: #0078D7;
border: none;
color: #fff;
border-radius: 5px;
cursor: pointer;
}
.btn:hover {
background-color: #0063B1;
}
</style>
</head>
<body>
<h1>TODOアプリ</h1>
<form>
<label>タイトル: <input type="text" id="title"></label>
<br>
<label>詳細: <input type="text" id="detail"></label>
<br>
<label>期限日: <input type="date" id="due_date"></label>
<br>
<button type="button" class="btn" onclick="addTodo()">追加</button>
</form>
<h2>TODOリスト</h2>
<ul id="todo_list"></ul>
<script>
//TODOリストを管理するオブジェクト
const todoList = {
//TODOリストの配列
list: [],
//TODOを追加するメソッド
addTodo: function(title, detail, dueDate) {
this.list.push({
title: title,
detail: detail,
dueDate: dueDate
});
//TODOリストを再描画する
this.renderTodoList();
},
//TODOを削除するメソッド
deleteTodo: function(index) {
this.list.splice(index, 1);
//TODOリストを再描画する
this.renderTodoList();
},
//TODOリストをHTMLとして描画するメソッド
renderTodoList: function() {
const todoListEl = document.getElementById('todo_list');
todoListEl.innerHTML = '';
this.list.forEach(function(todo, index) {
const liEl = document.createElement('li');
liEl.textContent = todo.title + ' - ' + todo.dueDate;
todoListEl.appendChild(liEl);
const deleteBtnEl = document.createElement('button');
deleteBtnEl.textContent = '削除';
deleteBtnEl.classList.add('btn');
deleteBtnEl.addEventListener('click', function() {
todoList.deleteTodo(index);
});
liEl.appendChild(deleteBtnEl);
});
}
};
//TODOを追加する関数
function addTodo() {
const titleEl = document.getElementById('title');
const detailEl = document.getElementById('detail');
const dueDateEl = document.getElementById('due_date');
const title = titleEl.value.trim();
const detail = detailEl.value.trim();
const dueDate = dueDateEl.value.trim();
//必須項目が入力されているか確認する
if (!title || !dueDate) {
alert('タイトルと期限日は必須です。');
return;
}
//TODOを追加する
todoList.addTodo(title, detail, dueDate);
//入力欄をクリアする
titleEl.value = '';
detailEl.value = '';
dueDateEl.value = '';
}
</script>
</body>
</html>
```
ジョークとして、削除ボタンを押したときに「本当に削除しますか?このTODOは一生あなたの心の中に生き続けますよ」というポップアップを出すといった演出を加えることもできます。