首页 > 解决方案 > 使用 javascript 删除 div 后无法读取 null 错误的属性“appendChild”

问题描述

请帮助:我在这里遇到了很多问题。我正在克隆 Trello,我已经能够创建一个输入字段并添加卡片。

(1)。第一个问题是多次单击添加卡片按钮会添加多张空白卡片,我只希望它一次添加一张卡片(带有用户添加的文本)

(2)。当我更改文本区域中的文本时,它会更改已创建卡片中的文本。应该使用用户的文本创建一张卡片,当用户再次单击添加卡片时,他/她应该能够创建具有不同文本的新卡片(而不是更改同一张卡片上的文本)。通常,用户每次单击“添加卡片”按钮时都应该能够添加具有不同文本的新卡片。

(3)。第三个问题是我似乎无法弄清楚如何在删除后重新添加另一个inputField 。当我单击添加另一张卡链接时,我收到此错误消息:“未捕获的类型错误:无法读取属性 'appendChild' of null”。

这是我的codepen的链接:https://codepen.io/Joanc/project/editor/ALkRVN

/*** ADD A CARD AND DELETE CARDS ***/

/*** Create and text-area (//for user input)// and add buttons for adding and deleting input***/
function displayInputField() {
  //Add an input field
  var a = document.getElementById("inputField");
  var b = document.createElement("textarea");
  b.setAttribute("type", "text");
  b.setAttribute("id", "userInput");
  b.setAttribute("overflow", "break-word");
  b.setAttribute("placeholder", "Enter a title for this card...");
  a.appendChild(b);

  //Add a "Add a Card" button
  var button = document.createElement("button");
  button.innerHTML = "Add Card";
  button.setAttribute("id", "createNewCard");
  a.appendChild(button);

  //Add a button for closing (X) Input
  var closeButton = document.createElement("closeButton");
  closeButton.innerHTML = '<i class="fas fa-times"></i>';
  closeButton.setAttribute("id", "createNewCloseBtn");
  a.appendChild(closeButton);
  createNewCloseBtn.addEventListener("click", function() {
    removeCard();
  });

  //Call the CreateCard function to create a new card after click.
  button.addEventListener("click", function() {
    createACard();
  });
}

//Hide the "Add a Card" link after click it.
function hideButton() {
  document.getElementById("addCardLink").style.visibility = "hidden"; // hide the button
}

//Creates a new card
function createACard() {
  var createCardElem = document.getElementById("createCard");
  var createNewCard = document.createElement("div");
  createNewCard.setAttribute("id", "newCard");
  createCardElem.appendChild(createNewCard);
  var inputTaker = document.getElementById('userInput').value;
  document.getElementById('newCard').innerHTML = inputTaker;
}

/** ADD A CARD **/

//removes the inputField and buttons from the document and shows the 'addAnotherCardLink' after it has been clicked.
function removeCard(inputField) {
  var element = document.getElementById("inputField");
  element.parentNode.removeChild(element);
  document.getElementById("addAnotherCardLink").style.display = "block";
  displayInputField();
}

function appendInputToCard() {
  var input = document.getElementById('input');
  var card =document.getElementById('newCard');
  var inputTaker = document.getElementById('input').value;
  document.getElementById('newCard').innerHTML = inputTaker;
}
body {
  font-family: "Roboto", sans-serif;
  font-family: "Open Sans", sans-serif;
  color: rgb(12,57,83);
}

/*** CARD COLUMNS ***/
/*** A temporary card holder ***/
.cardColumns {
  padding-top: 20px;
  max-width: 20%;
  /* height: 300px; */
  background-color: rgb(237, 239, 240);
  border-radius: 3px; /*** for rounded corners ***/
}

.cardColumns h4 {
  padding-left: 10px;
}

/*** CARD ***/

/*** Adding shadows for card effect ***/
.card,
#newCard {
  margin: 10px;
  box-shadow: 0 2px 4px 0 rgba(1, 1, 1, 0.2);
  border: none;
  border-radius: 3px; /*** for rounded corners ***/
  padding: 1px 20px;
  background-color: rgb(255, 255, 255);
  height: 50px; /* REMOVE AFTER YOUVE FIXED CARD */
  font-size: 14px;
}

.card:hover,
#newCard:hover {
  background-color: rgb(248, 249, 249);
}

textarea {
  margin-left: 10px;
  margin-bottom: 10px;
  width: 210px;
  /* width: 84%; */
  height: 50px;
  max-height: 120px;
  padding: 10px;
  font-size: 14px;
  box-shadow: 0 2px 4px 0 rgba(1, 1, 1, 0.2);
  border: none;
  border-radius: 3px; /*** for rounded corners ***/
  display: block;
}

.addCardBtn {
  font-size: 16px;
  font-weight: 600;
  color: rgb(255, 255, 255);
  padding: 8px 13px;
  background-color: rgb(90, 172, 68);
  box-shadow: 0 2px 4px 0 rgba(1, 1, 1, 0.2);
  border: none;
  border-radius: 3px; /*** for rounded corners ***/
  margin-top: 10px;
  margin-left: 10px;
}

button {
  font-size: 16px;
  font-weight: 600;
  color: rgb(255, 255, 255);
  padding: 8px 13px;
  background-color: rgb(90, 172, 68);
  box-shadow: 0 2px 4px 0 rgba(1, 1, 1, 0.2);
  border: none;
  border-radius: 3px; /*** for rounded corners ***/
  margin-top: 10px;
  margin-left: 10px;
  margin-bottom: 10px;
}

#createNewCloseBtn {
  color: rgb(131, 140, 145);
  font-size: 20px;
  margin-left: 10px;
}

a#addCardLink,
a#addAnotherCardLink {
  padding-left: 10px;
  text-decoration: none;
  color: rgb(131, 140, 145);
}

a#addCardLink:hover,
a#addAnotherCardLink:hover {
  text-decoration: underline;
  color: rgb(51, 51, 51);
}

a#addAnotherCardLink {
  display: none;
}
<!DOCTYPE html>
<html lang="en">

<head>

  <!-- Required meta tags -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta http-equiv="x-ua-compatible" content="ie-edge">
  <title></title>

  <!-- Link to CSS -->
  <link rel="stylesheet" type="text/css" href="css/styles.css">

  <!-- Link to Font-Awesome 5 -->
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU" crossorigin="anonymous">

  <!--Link to google fonts - Roboto and Open sans (400, 400 italics, 700 bold, 700 italics)-->
  <link href="https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700,700i|Roboto" rel="stylesheet">

</head>

<body>
  <!-- Temporary Card holder - will delete and create a modal -->
  <div class="cardColumns">
    <!-- Temporary heading -->
    <h4>General</h4>
    
    <!-- CARD -->
    
    <!-- Create card here -->
    <div id="createCard"></div>

    <!-- Create text-area and 'Add Card' and close 'X' buttons here -->
   
    <div id="inputField"></div>

    <!--AddCardLink - when clicked it adds an input field, and the buttons for adding a card and closing the input field. -->
    <a id="addCardLink" href="#" onclick="displayInputField(); hideButton();"><i class="fas fa-plus"></i> Add a Card</a>

    <a href="#" onclick="displayInputField()"><i class="fas fa-plus"></i> Add another Card</a>

  </div>
  <!-- Link to JavaScript -->
  <script src="js/scripts.js"></script>
</body>

</html>

标签: javascripthtmlcss

解决方案


因为一开始你是静态添加的,当你第一次调用displayInputField()HTML时没有错误。但是对于第二个,因为您已将其删除并且没有,您应该检查一下:div#inputFiled

var a = document.getElementById("inputField");
var inputFieldExist = true;
// null means we do not have div#inputField in our DOM so we should create it
if (a === null) {
    a = document.createElement("inputField");
    a.id = "inputField";
    // so we need to add this newly created element to our DOM
    inputFieldExist = false;
}
// var b = document.createElement("input");
var b = document.createElement("textarea");
...
...

这部分的第二个:

closeButton.setAttribute("id", "createNewCloseBtn");
a.appendChild(closeButton);
// we do not have "createNewCloseBtn"
createNewCloseBtn.addEventListener("click", function() {
    removeCard();
});

您添加了一个侦听器,createNewCloseBtnidclosedButton. 所以应该是:

closeButton.addEventListener("click", function() {
    removeCard();
});

inputField最后,如果它不存在,我们应该将新创建的添加到我们的 DOM 中:

if (!inputFieldExist) {
    document.querySelector('div.cardColumns').appendChild(a);
}
closeButton.addEventListener("click", function () {
    removeCard();
});

你需要做的最后一件事是删除/评论该displayInputField()功能以防止重复

function removeCard(inputField) {
    var element = document.getElementById("inputField");
    element.parentNode.removeChild(element);
    document.getElementById("addAnotherCardLink").style.display = "block";
    //displayInputField();

    // showButton();
    //   document.body.appendChild(element);
}

这是结果:https ://codepen.io/k-five/project/editor/XMMJGk


推荐阅读