Electron的本地存储未将我的点击事件保存在动态创建的元素上

时间:2018-11-21 07:04:12

标签: javascript html node.js local-storage electron

我正在使用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运行的,因此代码段并不完全准确。

如果我还没有把事情弄清楚,请随时问我一些问题,以消除混乱。

如果您对此有任何解决方案,或者有不良代码和做法的提示,我们将不胜感激。

谢谢。

1 个答案:

答案 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事件。这样,按钮单击事件将始终有效并通过本地存储正确保存。另外,在使用本地存储时,请务必注意范围。

希望这对其他人遇到此问题有帮助。