正如标题所说,我正在开发一个小项目,只是为了测试一些 DOM 操作。 我正在开发 Todo-List,用户可以创建一些名为(如工作、健身房、财务等)的列表,然后为每个类别添加一些子任务(单击 om work - 显示 subtask1、subtask2 等。 - 当你点击健身房时应该显示健身房的子任务等等。)。
现在,我陷入了用户可以单击主任务并在每次单击主任务时单独显示子任务的位置。
这几乎都是通过Javascript完成的。
let index = 1;
function displayTasks() {
const addButton = document.getElementById("addbutton");
addButton.addEventListener("click", function () {
createDialogTasks();
});
}
function createDialogTasks() {
const content = document.getElementById("content");
const dialog_tasks = document.createElement("dialog");
const input_dialog_task = document.createElement("input");
input_dialog_task.setAttribute("id", "input_create_task_name");
input_dialog_task.setAttribute("type", "text");
const create_task_name = document.createElement("button");
create_task_name.setAttribute("id", "create-button");
create_task_name.textContent = "Create";
create_task_name.addEventListener("click", function () {
createDialogButton(input_dialog_task, dialog_tasks);
});
const close_dialog_button = document.createElement("button");
close_dialog_button.textContent = "Close";
close_dialog_button.addEventListener("click", function () {
dialog_tasks.close();
});
content.appendChild(dialog_tasks);
dialog_tasks.appendChild(input_dialog_task);
dialog_tasks.appendChild(create_task_name);
dialog_tasks.appendChild(close_dialog_button);
dialog_tasks.showModal();
}
function displayTask(getTaskText) {
const div_new_task = document.getElementById("added-tasks");
const display_task_name = document.createElement("h1");
display_task_name.setAttribute("data", index);
display_task_name.textContent = getTaskText;
display_task_name.addEventListener("click", function () {
displayTaskName(getTaskText);
});
const delete_task_button = document.createElement("button");
delete_task_button.setAttribute("data", index);
delete_task_button.textContent = "delete";
delete_task_button.addEventListener("click", function () {
deleteTaskButton(display_task_name);
});
div_new_task.appendChild(display_task_name);
div_new_task.appendChild(delete_task_button);
}
function createDialogButton(input_dialog_task, dialog_tasks) {
if (input_dialog_task.value != "") {
displayTask(input_dialog_task.value);
dialog_tasks.close();
console.log(input_dialog_task.value);
} else {
alert("Insert at least a char");
}
index++;
}
function displayTaskName(getTaskText) {
const main_div = document.getElementById("main");
const test = document.createElement("button");
test.addEventListener("click", function () {
const mainText = document.createElement("p");
mainText.textContent = "test";
main_div.appendChild(mainText);
});
test.textContent = "New Task";
main_div.appendChild(test);
}
function deleteTaskButton(display_task_name) {
const id_element_to_delete = display_task_name.getAttribute("data");
const test = document.querySelectorAll(
"[data='" + id_element_to_delete + "']"
);
test.forEach((item) => {
item.outerHTML = "";
});
}
export default displayTasks;
这是完整的 JavaScript 代码。 我知道这不是最好的,而且可能很难阅读。如果需要的话我会尽力解释得更好。 不过,关于更好的格式和编码的建议值得赞赏,请随意,不要苛刻。
这是 HTML 骨架
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="\todo-list\dist\style.css" />
<title>Document</title>
</head>
<body>
<div id="content">
<div class="header">
<div class="header-text">My Todo List</div>
<img
src="/todo-list/src/assets/check-all.svg"
alt=""
class="header-logo"
/>
</div>
<div class="main-container">
<nav class="sidebar">
<div class="nav-text">
<img
src="/todo-list/src/assets/file-document-edit.svg"
alt=""
class="logo"
/>
<p class="title">My Tasks</p>
<button class="addbutton" id="addbutton">+</button>
</div>
<div class="added-tasks" id="added-tasks"></div>
<button class="deletebutton">Delete</button>
</nav>
<main class="main" id="main"></main>
</div>
<div class="footer">Created by Veglia Marco ⓒ</div>
</div>
<script src="main.js"></script>
</body>
</html>
目前,当我单击主任务时,创建后,它会显示一个用于创建子任务的按钮。但它们都是一起显示的。 我想不出一种方法来按照它应该工作的方式进行编码。所以我要问一些建议和想法来开始。 从来没有做过这样的事情,所以它开始变得有点棘手。
P.S:我正在使用 NPM。
提前致谢。
老实说,我不知道从哪里开始,我想过为每个元素创建单独的数组,然后单击后显示它们,但我不认为这是思考 DOM 的正确方法。
我希望主要内容能够正确更新,并为每个单击的主任务添加子任务。
好吧,我在数据属性的帮助下想出了一个可能的解决方案。
这是完整的代码,以防有人出于某种原因想要编写待办事项列表,并想要检查一些功能。 (CSS 还远未完成,但我希望逻辑已经完成。
此时,如果可以的话,我可以在代码中寻求建议,或者更好的方法来处理某些情况。
let index = 1;
let currentMain = null;
const addButton = document.getElementById("addbutton");
addButton.addEventListener("click", function () {
createDialogTasks();
});
function createDialogTasks() {
const content = document.getElementById("content");
const dialog_tasks = document.createElement("dialog");
const input_dialog_task = document.createElement("input");
input_dialog_task.setAttribute("id", "input_create_task_name");
input_dialog_task.setAttribute("type", "text");
const create_task_name = document.createElement("button");
create_task_name.setAttribute("id", "create-button");
create_task_name.textContent = "Create";
create_task_name.addEventListener("click", function () {
createDialogButton(input_dialog_task, dialog_tasks);
});
const close_dialog_button = document.createElement("button");
close_dialog_button.textContent = "Close";
close_dialog_button.addEventListener("click", function () {
dialog_tasks.close();
});
content.appendChild(dialog_tasks);
dialog_tasks.appendChild(input_dialog_task);
dialog_tasks.appendChild(create_task_name);
dialog_tasks.appendChild(close_dialog_button);
dialog_tasks.showModal();
}
function displayTask(getTaskText) {
const div_new_task = document.getElementById("added-tasks");
const display_task_name = document.createElement("h1");
const taskID = index;
display_task_name.setAttribute("data", index);
display_task_name.classList.add("task_name");
display_task_name.textContent = getTaskText;
display_task_name.addEventListener("click", function () {
const taskID = display_task_name.getAttribute("data");
const main = document.querySelector(`[data-main-for="${taskID}"]`);
if (main) {
if (currentMain) {
currentMain.style.display = "none"; // Hide the current main
}
currentMain = main;
currentMain.style.display = "block"; // Show the new current main
} else {
if (currentMain) {
currentMain.style.display = "none"; // Hide the current main
}
currentMain = displayTaskName(taskID); // Set the new current main
}
const actives = document.querySelectorAll(".active");
actives.forEach((active) => {
active.classList.remove("active");
});
display_task_name.classList.add("active");
if (display_task_name.classList.contains("active")) {
display_task_name.style.display = "block";
} else {
display_task_name.style.display = "none";
}
});
const delete_task_button = document.createElement("button");
delete_task_button.setAttribute("data", index);
delete_task_button.textContent = "delete";
delete_task_button.addEventListener("click", function () {
deleteTaskButton(display_task_name);
});
div_new_task.appendChild(display_task_name);
div_new_task.appendChild(delete_task_button);
index++;
}
function createDialogButton(input_dialog_task, dialog_tasks) {
if (input_dialog_task.value != "") {
displayTask(input_dialog_task.value);
dialog_tasks.close();
console.log(input_dialog_task.value);
} else {
alert("Insert at least a char");
}
}
function displayTaskName(taskID) {
const main_container = document.getElementById("main-container");
const main = document.createElement("main");
main.setAttribute("data-main-for", taskID);
main.style.display = "block"; // Show the new main
const test = document.createElement("button");
main.appendChild(test);
test.addEventListener("click", function () {
main.appendChild(createSubTask());
});
test.textContent = "New Task";
main_container.appendChild(main);
return main;
}
function deleteTaskButton(display_task_name) {
const id_element_to_delete = display_task_name.getAttribute("data");
const test = document.querySelectorAll(
"[data='" + id_element_to_delete + "']"
);
test.forEach((item) => {
item.outerHTML = "";
});
}
function createSubTask() {
const sub_task_dialog = document.createElement("dialog");
const checkbox = document.createElement("input");
checkbox.setAttribute("type", "checkbox");
const sub_task_input = document.createElement("input");
sub_task_input.setAttribute("type", "text");
const calendar = document.createElement("input");
calendar.setAttribute("type", "date");
const close_sub_task_button = document.createElement("button");
close_sub_task_button.textContent = "Close";
close_sub_task_button.addEventListener("click", function () {
sub_task_dialog.close();
});
const submit_sub_task_button = document.createElement("button");
submit_sub_task_button.textContent = "Submit";
submit_sub_task_button.addEventListener("click", function () {
const subTaskInfo = {
isChecked: checkbox.checked,
taskName: sub_task_input.value,
date: calendar.value,
};
displaySubTaskInfo(subTaskInfo);
sub_task_dialog.close();
});
sub_task_dialog.appendChild(checkbox);
sub_task_dialog.appendChild(sub_task_input);
sub_task_dialog.appendChild(calendar);
sub_task_dialog.appendChild(submit_sub_task_button);
sub_task_dialog.appendChild(close_sub_task_button);
sub_task_dialog.show();
return sub_task_dialog;
}
function displaySubTaskInfo(subTaskInfo) {
if (currentMain) {
const subTaskDiv = document.createElement("div");
const dateElement = document.createElement("p");
dateElement.setAttribute("id", "sub-date");
dateElement.textContent = `Date: ${subTaskInfo.date}`;
const nameElement = document.createElement("p");
nameElement.setAttribute("id", "sub-name");
nameElement.textContent = `Name: ${subTaskInfo.taskName}`;
const checkboxElement = document.createElement("input");
checkboxElement.setAttribute("id", "sub-check");
checkboxElement.setAttribute("type", "checkbox");
checkboxElement.checked = subTaskInfo.isChecked;
const editButton = document.createElement("button");
editButton.textContent = "Edit";
editButton.addEventListener("click", function () {
openEditSubTaskDialog(subTaskDiv, subTaskInfo);
});
const delete_sub_task = document.createElement("button");
delete_sub_task.textContent = "Delete";
delete_sub_task.addEventListener("click", function () {
currentMain.removeChild(subTaskDiv);
if (currentMain.querySelectorAll("div").length === 0) {
const newTaskButton = currentMain.querySelector("button");
if (newTaskButton) {
newTaskButton.style.display = "block";
}
}
});
subTaskDiv.appendChild(checkboxElement);
subTaskDiv.appendChild(nameElement);
subTaskDiv.appendChild(dateElement);
subTaskDiv.appendChild(editButton);
subTaskDiv.appendChild(delete_sub_task);
currentMain.appendChild(subTaskDiv);
const subTasksExist = currentMain.querySelector("div");
if (subTasksExist) {
const newTaskButton = currentMain.querySelector("button");
if (newTaskButton) {
newTaskButton.style.display = "none";
}
}
}
}
function openEditSubTaskDialog(subTaskDiv, subTaskInfo) {
const editSubTaskDialog = document.createElement("dialog");
const editNameInput = document.createElement("input");
editNameInput.setAttribute("type", "text");
editNameInput.value = subTaskInfo.taskName;
const editDateInput = document.createElement("input");
editDateInput.setAttribute("type", "date");
editDateInput.value = subTaskInfo.date;
const editCheckboxInput = document.createElement("input");
editCheckboxInput.setAttribute("type", "checkbox");
editCheckboxInput.checked = subTaskInfo.isChecked;
const saveButton = document.createElement("button");
saveButton.textContent = "Save";
saveButton.addEventListener("click", function () {
subTaskInfo.taskName = editNameInput.value;
subTaskInfo.date = editDateInput.value;
subTaskInfo.isChecked = editCheckboxInput.checked;
subTaskDiv.querySelector(
"#sub-date"
).textContent = `Date: ${subTaskInfo.date}`;
subTaskDiv.querySelector("#sub-check").checked = subTaskInfo.isChecked;
subTaskDiv.querySelector("#sub-name").textContent = subTaskInfo.taskName;
editSubTaskDialog.close();
});
const cancelButton = document.createElement("button");
cancelButton.textContent = "Cancel";
cancelButton.addEventListener("click", function () {
editSubTaskDialog.close();
});
editSubTaskDialog.appendChild(editCheckboxInput);
editSubTaskDialog.appendChild(editNameInput);
editSubTaskDialog.appendChild(editDateInput);
editSubTaskDialog.appendChild(saveButton);
editSubTaskDialog.appendChild(cancelButton);
document.body.appendChild(editSubTaskDialog);
editSubTaskDialog.showModal();
}
@font-face {
font-family: "OpenSansLight";
src: url("fonts/fonts/OpenSans-Light-webfont.eot");
src: url("fonts/OpenSans-Light-webfont.eot?#iefix")
format("embedded-opentype"),
url("/todo-list/src/assets/fonts/OpenSans-Light.ttf") format("truetype"),
url("fonts/OpenSans-Light-webfont.svg#OpenSansLight") format("svg");
font-weight: normal;
font-style: normal;
}
* {
margin: 0;
font-family: OpenSansLight;
font-size: 20px;
}
body {
background-color: lightcoral;
display: flex;
justify-content: center;
align-items: center;
width: 100wh;
height: 100vh;
}
#content {
display: grid;
grid-column: 1fr 2fr;
height: 400px;
width: 800px;
border: 5px solid;
border-radius: 10px;
}
.sidebar {
border: 1px solid;
}
.header {
display: grid;
grid-template-columns: 0.5fr 0.8fr 1fr;
column-gap: 5px;
height: 30px;
border: 1px solid;
}
.header-text {
text-align: right;
grid-column: 2 / 3;
}
.main-container {
border: 1px solid;
display: grid;
grid-template-columns: 1fr 2fr;
height: 48.5vh;
}
.nav-text {
margin: 5px;
display: grid;
grid-template-columns: 0.16fr 1fr 1.4fr;
}
.addbutton {
width: 27px;
border-radius: 15px;
scale: 0.8;
border: none;
}
.addbutton:hover {
background-color: green;
box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.24), 0 17px 50px 0 rgba(0, 0, 0, 0.19);
}
.addbutton:active {
background-color: #3e8e41;
box-shadow: 0 1px #666;
transform: translateY(2px);
}
.deletebutton {
margin: 7px;
}
.deletebutton:hover {
background-color: red;
box-shadow: 0 4px 4px 0 rgba(0, 0, 0, 0.24), 0 17px 50px 0 rgba(0, 0, 0, 0.19);
}
.deletebutton:active {
background-color: #df5454;
box-shadow: 0 1px #666;
transform: translateY(2px);
}
.footer {
text-align: center;
margin-top: 10px;
}
.active {
background-color: orange;
}
.task_name:hover {
background-color: yellow;
}
.sub-tasks-div {
border: 1px solid;
font-size: 16px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<div id="content">
<div class="header">
<div class="header-text">My Todo List</div>
<img
src="/todo-list/src/assets/check-all.svg"
alt=""
class="header-logo"
/>
</div>
<div class="main-container" id="main-container">
<nav class="sidebar">
<div class="nav-text">
<img
src="/todo-list/src/assets/file-document-edit.svg"
alt=""
class="logo"
/>
<p class="title">My Tasks</p>
<button class="addbutton" id="addbutton">+</button>
</div>
<div class="added-tasks" id="added-tasks"></div>
</nav>
</div>
<div class="footer">Created by Veglia Marco ⓒ</div>
</div>
<script src="main.js"></script>
</body>
</html>
谢谢。