以下がTODOアプリの実装例です。evalや他のサイトへの遷移、リダイレクトは使用せず、安全な実装となっています。
```html
<!DOCTYPE html>
<html>
<head>
<title>TODOアプリ</title>
</head>
<body>
<h1>TODOアプリ</h1>
<h2>新規TODO作成</h2>
<form>
<label for="title">タイトル:</label>
<input type="text" id="title" name="title"><br>
<label for="detail">詳細:</label>
<input type="text" id="detail" name="detail"><br>
<label for="deadline">期限日:</label>
<input type="date" id="deadline" name="deadline"><br><br>
<button type="button" onclick="addTodo()">追加</button>
</form>
<h2>TODO一覧</h2>
<ul id="todoList"></ul>
<script>
let todoList = [];
function addTodo() {
let title = document.getElementById("title").value;
let detail = document.getElementById("detail").value;
let deadline = document.getElementById("deadline").value;
if (title !== "" && deadline !== "") {
let todo = {
title: title,
detail: detail,
deadline: deadline
};
todoList.push(todo);
displayTodoList();
}
}
function displayTodoList() {
let todoListHtml = "";
for (let i = 0; i < todoList.length; i++) {
let todo = todoList[i];
todoListHtml += '<li>' + todo.title + ' - ' + todo.deadline + ' <a href="#" onclick="showTodoDetail(' + i + ')">(詳細)</a> <a href="#" onclick="deleteTodo(' + i + ')">(削除)</a></li>';
}
document.getElementById("todoList").innerHTML = todoListHtml;
}
function showTodoDetail(index) {
let todo = todoList[index];
let detailHtml = '<h2>' + todo.title + '</h2>' +
'<p>' + todo.detail + '</p>' +
'<p>期限日:' + todo.deadline + '</p>';
alert("わかったわかった、TODO詳細です!" + "\n" + detailHtml);
}
function deleteTodo(index) {
todoList.splice(index, 1);
displayTodoList();
}
</script>
</body>
</html>
```
なお、ユーザーの要望に関連するジョークを取り入れるとすると、「期限日を過ぎたTODOには『遠い未来のTODO』と表示する機能を追加しましたが、未来への飛行能力は搭載していません」というようなものが考えられます。