我正在使用Electron创建一个桌面应用程序,并且遇到了有关单击事件本地存储的问题。
在我的应用程序中,用户输入5组信息(出版物名称,发布者名称,状态,提交日期,响应日期)
然后将信息通过D.O.M放入HTML表中,在该表中按信息类别按条目将行划分为行,并在最右边的列中按“删除”和“编辑”按钮将其分隔。
例如
| name1 | publisher1 | awaiting | noDate | NoDate2 | [RemoveButton] [EditButton] |
| name2 | publisher2 | denied | noDate3 | NoDate4 | [RemoveButton] | [EditButton] |
| name3 | publisher3 | accepted | noDate5 | NoDate6 | [RemoveButton] | [EditButton] |
,依此类推,随着用户输入更多的条目,更多的行将附加到表中。但是,附加的每一行始终在右侧具有2个“删除”和“编辑”按钮。我已经为这两个按钮分配了一个功能,如下所示:
“删除”按钮:
editButton.addEventListener("click", function() {
if (confirm("Are you sure you want to delete this item?")) {
var td = event.target.parentNode;
var tr = td.parentNode;
tr.parentNode.removeChild(tr);
localStorage.setItem("TableStorage", table.innerHTML);
} else {}
};
“编辑”按钮:
editButton.addEventListener("click", function() {
if (confirm("Are you sure you want to edit this item?")) {
var publicationName = document.getElementById("publicationNameTextField");
var publisherName = document.getElementById("publisherNameTextField");
var publicationStatus = document.getElementById(
"publicationStatusTextField"
);
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
);
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
);
var table = document.getElementById("myTable");
var td = event.target.parentNode;
var tr = td.parentNode;
rowIndex = tr.rowIndex;
var cell1 = table.rows[rowIndex].cells[0].innerHTML;
var cell2 = table.rows[rowIndex].cells[1].innerHTML;
var cell3 = table.rows[rowIndex].cells[2].innerHTML;
var cell4 = table.rows[rowIndex].cells[3].innerHTML;
var cell5 = table.rows[rowIndex].cells[4].innerHTML;
publicationName.value = cell1;
publisherName.value = cell2;
publicationStatus.value = cell3;
publicationDateSubmitted.value = cell4;
publicationDateResponse.value = cell5;
publicationName.focus();
localStorage.setItem("TableStorage", table.innerHTML);
tr.parentNode.removeChild(tr);
} else {}
};
(要进一步详细说明编辑按钮,它将删除该按钮所在的行,然后将所有列条目的出版物名称,状态等重新输入到要修改和重新提交的文本字段中。)
(代码格式化可能不准确,因为我不习惯在此处格式化代码)
这些按钮在活动会话期间(当应用程序运行时添加了提交)发挥了作用,但是当我关闭该应用程序并重新打开它和/或强制重新加载它时,这些按钮似乎失去了功能。我认为这与我如何存储本地存储有关。
我发现确实很奇怪,但是,我有一个“清除所有按钮”,该按钮实际上清除了表中的所有内容。此按钮的格式设置与其他按钮相同,但不会像其他按钮那样动态生成。因此,它使我相信函数的声明方式存在问题。
var clearBtn = document.getElementById("clearAllButton");
clearBtn.addEventListener("click", function() {
if (confirm("Are you sure you want to clear your Publications?")) {
for (var i = 1; i < table.rows.length; ) {
table.deleteRow(i);
localStorage.setItem("TableStorage", table.innerHTML);
}
} else {
}
});
这是完整的代码段:
// ALL javascript code that interacts with the page is used here.
// This code is required in the HTML by a require('renderer.js) and thus runs from the page.
// The DOM can be accessed from this file.
// Declare variables from document
//var publicationName = document.getElementById('publicationNameTextField');
//var publisherName = document.getElementById('publisherNameTextField');
//var publicationStatus = document.getElementById('publicationStatusTextField');
//var publicationDateSubmitted = document.getElementById('publicationDateSubmittedTextField');
//var publicationDateResponse = document.getElementById('publicationDateResponseTextField');
"use strict";
// Save Data on close
window.onclose = function() {
localStorage.setItem("TableStorage", table.innerHTML);
};
// Save data failsafe in event of crash
window.onabort = function() {
localStorage.setItem("TableStorage", table.innerHTML);
};
// Declare submit button
var submitBtn = document.getElementById("submitButton");
// Declare table data will be displayed and saved to
var table = document.getElementById("myTable");
// Get value of textfields from DOM
var publicationName = document.getElementById("publicationNameTextField").value;
var publisherName = document.getElementById("publisherNameTextField").value;
var publicationStatus = document.getElementById("publicationStatusTextField")
.value;
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
).value;
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
).value;
// Create a event listener for when the add button is pressed.
submitBtn.addEventListener("click", function(o) {
// Re declare variables for scope
var table = document.getElementById("myTable");
var publicationName = document.getElementById("publicationNameTextField")
.value;
var publisherName = document.getElementById("publisherNameTextField").value;
var publicationStatus = document.getElementById("publicationStatusTextField")
.value;
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
).value;
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
).value;
// Save values entered as possible option entries for later submissions.
var publicationNameDataList = document.getElementById(
"publicationNameDataList"
);
var publicationNameOption = document.createElement("option");
publicationNameOption.innerHTML = publicationName;
publicationNameDataList.appendChild(publicationNameOption);
var publisherNameDataList = document.getElementById("publisherNameDataList");
var publisherNameOption = document.createElement("option");
publisherNameOption.innerHTML = publisherName;
publisherNameDataList.appendChild(publisherNameOption);
var publicationDateSubmittedDataList = document.getElementById(
"publicationDateSubmittedDataList"
);
var publicationDateSubmittedOption = document.createElement("option");
publicationDateSubmittedOption.innerHTML = publicationDateSubmitted;
publicationDateSubmittedDataList.appendChild(publicationDateSubmittedOption);
var publicationDateResponseDataList = document.getElementById(
"publicationDateResponseDataList"
);
var publicationDateResponseOption = document.createElement("option");
publicationDateResponseOption.innerHTML = publicationDateResponse;
publicationDateResponseDataList.appendChild(publicationDateResponseOption);
// Add a button to remove the particular row on each row
var deleteButton = document.createElement("img");
deleteButton.className = "deleteButton";
deleteButton.innerHTML = "Remove";
deleteButton.addEventListener("click", function() {
if (confirm("Are you sure you want to delete this item?")) {
var td = event.target.parentNode;
var tr = td.parentNode;
tr.parentNode.removeChild(tr);
localStorage.setItem("TableStorage", table.innerHTML);
} else {}
});
deleteButton.src = "assets/img/icons8-cancel-48.png";
var editButton = document.createElement("img");
editButton.className = "editButton";
editButton.innerHTML = "Edit";
editButton.addEventListener("click", function() {
if (confirm("Are you sure you want to edit this item?")) {
var publicationName = document.getElementById("publicationNameTextField");
var publisherName = document.getElementById("publisherNameTextField");
var publicationStatus = document.getElementById(
"publicationStatusTextField"
);
var publicationDateSubmitted = document.getElementById(
"publicationDateSubmittedTextField"
);
var publicationDateResponse = document.getElementById(
"publicationDateResponseTextField"
);
var table = document.getElementById("myTable");
var td = event.target.parentNode;
var tr = td.parentNode;
rowIndex = tr.rowIndex;
var cell1 = table.rows[rowIndex].cells[0].innerHTML;
var cell2 = table.rows[rowIndex].cells[1].innerHTML;
var cell3 = table.rows[rowIndex].cells[2].innerHTML;
var cell4 = table.rows[rowIndex].cells[3].innerHTML;
var cell5 = table.rows[rowIndex].cells[4].innerHTML;
publicationName.value = cell1;
publisherName.value = cell2;
publicationStatus.value = cell3;
publicationDateSubmitted.value = cell4;
publicationDateResponse.value = cell5;
publicationName.focus();
localStorage.setItem("TableStorage", table.innerHTML);
tr.parentNode.removeChild(tr);
} else {}
});
editButton.src = "assets/img/icons8-edit-file-40.png";
// Create cells for each row
var row = table.insertRow(1);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);
var cell4 = row.insertCell(3);
var cell5 = row.insertCell(4);
var cell6 = row.insertCell(5);
var cell7 = row.insertCell(6);
// Give each cell of the row content from the textfields
cell1.innerHTML = publicationName;
cell2.innerHTML = publisherName;
cell3.innerHTML = publicationStatus;
cell4.innerHTML = publicationDateSubmitted;
cell5.innerHTML = publicationDateResponse;
cell6.appendChild(deleteButton);
cell7.appendChild(editButton);
// Save data to localstorage
localStorage.setItem("TableStorage", table.innerHTML);
// Clear text fields for next entry
document.getElementById("publicationNameTextField").value = "";
document.getElementById("publisherNameTextField").value = "";
document.getElementById("publicationStatusTextField").value = "";
document.getElementById("publicationDateSubmittedTextField").value = "";
document.getElementById("publicationDateResponseTextField").value = "";
});
// Load previous data upon application loading
window.onload = function() {
var saved = localStorage.getItem("TableStorage");
// If there are any saved items, update our list
if (saved) {
table.innerHTML = saved;
}
};
// Clear Button to clear all items of the table.
var clearBtn = document.getElementById("clearAllButton");
clearBtn.addEventListener("click", function() {
if (confirm("Are you sure you want to clear your Publications?")) {
for (var i = 1; i < table.rows.length; ) {
table.deleteRow(i);
localStorage.setItem("TableStorage", table.innerHTML);
}
} else {
}
});
body {
font-family: Arial, Helvetica, sans-serif;
}
* {
box-sizing: border-box;
}
#form {
text-align: center;
}
.input-container {
display: -ms-flexbox;
/* IE10 */
display: flex;
width: 100%;
margin-bottom: 15px;
text-align: left;
}
.blueB {
padding: 10px;
background: dodgerblue;
color: white;
min-width: 50px;
text-align: center;
}
.input-field {
width: 100%;
padding: 10px;
outline: none;
}
.input-field:focus {
border: 2px solid dodgerblue;
}
/* Set a style for the submit button */
.btn {
background-color: dodgerblue;
color: white;
padding: 15px 20px;
border: none;
cursor: pointer;
width: 50%;
opacity: 0.9;
}
.btn:hover {
opacity: 1;
}
img:hover {
transform: scale(1.1);
cursor: pointer;
}
/* Style the main content */
.main {
/* Same as the width of the sidenav */
padding: 0px 10px;
}
/* Add media queries for small screens (when the height of the screen is less than 450px, add a smaller padding and font-size) */
@media screen and (max-height: 450px) {
.sidebar {
padding-top: 15px;
}
.sidebar a {
font-size: 18px;
}
}
p {
color: white;
}
h1 {
color: #3500D3;
}
h2 {
color: white;
}
#myInput {
background-image: url('../assets/img/icons8-search-32.png');
/* Add a search icon to input */
background-position: 10px 10px;
/* Position the search icon */
background-repeat: no-repeat;
/* Do not repeat the icon image */
width: 100%;
/* Full-width */
font-size: 16px;
/* Increase font-size */
padding: 12px 20px 12px 40px;
/* Add some padding */
border: 1px solid #3500D3;
/* Add a grey border */
margin-bottom: 12px;
/* Add some space below the input */
}
.PublicationShow {
height: 50%;
width: 100%;
overflow: auto;
}
#myTable {
border-collapse: collapse;
/* Collapse borders */
width: 100%;
/* Full-width */
border: 1px solid #3500D3;
/* Add a grey border */
font-size: 18px;
height: 50%;
overflow-y: auto;
/* Increase font-size */
text-align: center;
}
#myTable th,
#myTable td {
text-align: center;
/* Left-align text */
padding: 12px;
/* Add padding */
}
#myTable tr {
/* Add a bottom border to all table rows */
border-bottom: 1px solid #ddd;
}
#myTable tr.header,
#myTable tr:hover {
/* Add a grey background color to the table header and on hover */
background-color: #3500D3;
}
td {
color: white;
}
#clearItemText {
display: inline;
text-align: center;
top: 50%;
}
.deleteButton {
border-radius: 50%;
}
.editButton {
border-radius: 50%;
}
.trashHover {
background-color: none !important;
color: white;
font-size: 35px;
}
.trashHover:hover {
transform: scale(1.1);
cursor: pointer;
color: #fb0253;
}
<!DOCTYPE html>
<html style="width: 100%; height: 90%; background-color: #190061">
<head>
<meta charset="UTF-8" />
<title>Easy Track | Publication Manager</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU"
crossorigin="anonymous" />
<link rel="stylesheet" href="css/index.css" />
</head>
<body style="width: 100%; height: 90%; background-color: #190061">
<!-- All of the Node.js APIs are available in this renderer process. -->
<div class="main">
<h1>Easy Track | Publication Manager</h1>
<br />
<p>Manage your publications and submissions with ease!</p>
<br />
<div id="form" style="margin:auto">
<h2>Add Publication</h2>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationNameTextField" class="input-field" type="text" placeholder="Publication Name" name="publicationName"
list="publicationNameDataList" />
<datalist id="publicationNameDataList"> </datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publisherNameTextField" class="input-field" type="text" placeholder="Publisher Name" name="publisherName"
list="publisherNameDataList" />
<datalist id="publisherNameDataList"> </datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationStatusTextField" class="input-field" type="text" placeholder="Status" name="publicationStatus"
list="statusList" />
<datalist id="statusList">
<option>Awaiting</option>
<option>Denied</option>
<option>Accepted</option>
</datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationDateSubmittedTextField" class="input-field" type="text" placeholder="Date Submitted" name="publicationDateSubmitted"
list="publicationDateSubmittedDataList" />
<datalist id="publicationDateSubmittedDataList"> </datalist>
</div>
<div class="input-container">
<i class="blueB"></i>
<input id="publicationDateResponseTextField" class="input-field" type="text" placeholder="Date of Response"
list="publicationDateResponseDataList" name="publicationDateResponse" />
<datalist id="publicationDateResponseDataList"> </datalist>
</div>
<button id="submitButton" class="btn">Submit</button> <br />
</div>
<br />
<br />
<div class="PublicationsShow">
<input type="text" id="myInput" onkeyup="searchBar()" placeholder="Search" />
<br />
<i id="clearAllButton" class="fas fa-trash-alt trashHover"></i>
<p id="clearItemText">Clear All Items</p>
<table id="myTable">
<tr class=" header">
<th style="width:15%; color: white !important;">
Publication name
</th>
<th style="width:15%; color: white !important;">Publisher Name</th>
<th style="width:15%; color: white !important;">Status</th>
<th style="width:15%; color: white !important;">Date Submitted</th>
<th style="width:15%; color: white !important;">
Date of Response
</th>
<th style="width:15%; color: white !important;">Change</th>
</tr>
</table>
</div>
</div>
<script>
// You can also require other files to run in this process
require("./js/renderer.js");
function filterTable(event) {
var filter = event.target.value.toUpperCase();
var rows = document.querySelector("#myTable tbody").rows;
for (var i = 1; i < rows.length; i++) {
var firstCol = rows[i].cells[0].textContent.toUpperCase();
var secondCol = rows[i].cells[1].textContent.toUpperCase();
var thirdCol = rows[i].cells[2].textContent.toUpperCase();
var fourthCol = rows[i].cells[3].textContent.toUpperCase();
var fifthCol = rows[i].cells[4].textContent.toUpperCase();
if (
firstCol.indexOf(filter) > -1 ||
secondCol.indexOf(filter) > -1 ||
thirdCol.indexOf(filter) > -1 ||
fourthCol.indexOf(filter) > -1 ||
fifthCol.indexOf(filter) > -1
) {
rows[i].style.display = "";
} else {
rows[i].style.display = "none";
}
}
}
document
.querySelector("#myInput")
.addEventListener("keyup", filterTable, false);
</script>
</body>
</html>
由于我的应用程序是通过Node和Electron运行的,因此代码段并不完全准确。
如果我还没有把事情弄清楚,请随时问我一些问题,以消除混乱。
如果您对此有任何解决方案,或者有不良代码和做法的提示,我们将不胜感激。
谢谢。
答案 0 :(得分:0)
进一步检查后,我发现了问题所在。在会话中已分配了按钮上的单击事件,但本地存储无法存储事件,因为它们不是字符串。
要解决此问题:
将“单击”事件保留在“添加”按钮上,以便它们在会话中起作用,但在页面加载时为您要使用的按钮添加一个for循环。单击按钮时,请确保为元素分配一个类,以在页面加载时对其进行引用。
例如
window.onload = function() {
var savedInner = localStorage.getItem("listStorageInner");
var savedOuter = localStorage.getItem("listStorageOuter");
// If there are any saved items, update our list
if (savedInner) {
let targetList = document.getElementById("projectList");
targetList.innerHTML = savedInner;
}
if (savedOuter) {
let targetList = document.getElementById("projectList");
targetList.outerHTML = savedOuter;
}
var removeButtons = document.getElementsByClassName("removeMeBtn");
for (let i = 0; i < removeButtons.length; i++) {
removeButtons[i].addEventListener(
"click",
(function() {
return function() {
let parent = this.parentElement;
parent.parentElement.removeChild(parent);
let targetList = document.getElementById("projectList");
localStorage.removeItem("listStorageInner", targetList.innerHTML);
localStorage.removeItem("listStorageOuter", targetList.outerHTML);
localStorage.setItem("listStorageInner", targetList.innerHTML);
localStorage.setItem("listStorageOuter", targetList.outerHTML);
};
})(i),
false
);
}
var editBtns = document.getElementsByClassName("editMeBtn");
for (let j = 0; j < editBtns.length; j++) {
editBtns[j].addEventListener(
"click",
(function() {
return function() {
let parent = this.parentElement;
document.getElementById("entryInput").value = parent.textContent;
parent.focus();
parent.parentElement.removeChild(parent);
let targetList = document.getElementById("projectList");
localStorage.removeItem("listStorageInner", targetList.innerHTML);
localStorage.removeItem("listStorageOuter", targetList.outerHTML);
localStorage.setItem("listStorageInner", targetList.innerHTML);
localStorage.setItem("listStorageOuter", targetList.outerHTML);
};
})(j),
false
);
}
};
for循环遍历具有按钮类名称的所有元素,然后在页面加载时分配onclick事件。这样,按钮单击事件将始终有效并通过本地存储正确保存。另外,在使用本地存储时,请务必注意范围。
希望这对其他人遇到此问题有帮助。