开发者问题收集

我在设置 <tbody> 标签的 innerHTML 时遇到了问题。使用 document.getElementById 选择它后,它显示错误

2021-11-07
541

我所做的就是使用 document.getElementByID("tableBody") 从我的 html 代码中获取 tbody 标签,然后尝试使用 javascript 添加一些行。但是每当我尝试设置 tbody 标签的 innerHTML 属性时,它都会显示此错误。

index2.js:38 Uncaught TypeError: Cannot set properties of null (setting 'innerHTML')
    at Display.add (index2.js:38)
    at HTMLButtonElement.<anonymous> (index2.js:90)

我不知道为什么会出现此错误,我多次重新查看了我的代码。请帮助我

HTML 代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Reading</title>

    <!-- CSS of the bootstrap  -->
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
        integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">

    <!-- Custom CSS  -->
    <link rel="stylesheet" href="CSS/style.css">

    <!-- Google Fonts  -->
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Leckerli+One&display=swap" rel="stylesheet">

    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Serif:wght@400;700&display=swap" rel="stylesheet">

    <!-- Fontawesome cdn  -->
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" integrity="sha384-DyZ88mC6Up2uqS4h/KRgHuoeGwBcD4Ng9SiP4dIRy0EXTlnuz47vAwmeGwVChigm" crossorigin="anonymous">

</head>

<body>

    <!-- Navbar Code  -->
    <nav class="navbar navbar-expand-lg navbar-dark bg-dark">

        <a href="#" class="navbar-brand navbar-expand-lg navbar-dark bg">READINGS</a>

        <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarTogglerDemo01"
            aria-controls="navbarTogglerDemo01" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>

        <div id="navbarTogglerDemo01" class="collapse navbar-collapse">
            <ul class="navbar-nav mr-auto">
                <li class="nav-item"> <a href="#" class="nav-links">Home</a></li>
            </ul>
        </div>
    </nav>

    <!-- library detail code starts  -->
    <div class="container-fluid form-section">
        <h1>My Reading Library</h1>

        <!-- Form section  -->
        <div class="container form-holder-div">

            <form id="libraryForm">
                <div class="form-group row">
                    <label for="bookName" class="col-sm-2 col-form-label">Book Name</label>
                    <div class="col-sm-10">
                        <input type="text" class="form-control" id="bookName">
                    </div>
                </div>
                <div class="form-group row">
                    <label for="AuthorName" class="col-sm-2 col-form-label">Author of the book</label>
                    <div class="col-sm-10">
                        <input type="text" class="form-control" id="authorName">
                    </div>
                </div>
                <fieldset class="form-group row">
                    <legend class="col-form-label col-sm-2 float-sm-left pt-0">Type</legend>
                    <div class="col-sm-10">
                        <div class="form-check">
                            <input class="form-check-input" type="radio" name="bookType" id="Fiction" value="fiction"
                                checked>
                            <label class="form-check-label" for="fiction">
                                Fiction
                            </label>
                        </div>
                        <div class="form-check">
                            <input class="form-check-input" type="radio" name="bookType" id="Programming"
                                value="programming">
                            <label class="form-check-label" for="Programming">
                                Programming
                            </label>
                        </div>
                        <div class="form-check">
                            <input class="form-check-input" type="radio" name="bookType" id="Cooking" value="cooking">
                            <label class="form-check-label" for="Cooking">
                                Cooking
                            </label>
                        </div>
                    </div>
                </fieldset>
                <div class="form-group row">
                    <div class="col-sm-10">
                        <button type="submit" class="btn btn-primary" style="font-weight: 700;" id="addButton">Add Book</button>
                    </div>
                </div>
            </form>
        </div>
    </div>

    <!-- table section  -->
    <div class="container-fluid table-section" id="tableArea">
        <table class="table">
            <thead class="thead-dark">
                <tr>
                    <th scope="col">#</th>
                    <th scope="col">Book Name</th>
                    <th scope="col">Author Name</th>
                    <th scope="col">Type</th>
                    <th scope="col">Operation</th>
                </tr>
            </thead>

            <tbody id="tableBody">
                
            </tbody>
        </table>
    </div>

    <div class="footer-section">
        <h1><i class="far fa-copyright"> </i> Made with <i class="far fa-laugh-wink"></i> by TheNullPerson</h1>
    </div>

    <!-- This is the bootstrap javaScript -->
    <script src="javascript/index2.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.slim.min.js"
        integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj"
        crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js"
        integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN"
        crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js"
        integrity="sha384-VHvPCCyXqtD5DqJeNxl2dtTyhF78xXNXdkwX1CZeRusQfRKp+tA7hAShOK/B/fQ2"
        crossorigin="anonymous"></script>
</body>

</html>

JavaScript 代码:

var bookObj = [];
/*  Display Class with the following methods:
1) .add(book) => to add book(array of book objects) to the table element 
2) .clear => to clear the element from the text fields
*/
function Display() {
}
// .add() method 
Display.prototype.add = function () {
    let bookElements = localStorage.getItem("books");
    if (bookElements === null) {
        bookObj = [];
    } else {
        bookObj = JSON.parse(bookElements);
        console.log(typeof bookObj);
    }

    console.log(bookObj);
    let html = "";
    let Element;
    if (bookObj.length === 0) {
        html = "<h1>Please add some content from above section</h1>";
        Element = document.getElementById("tableArea");
        Element.innerHTML = html;
    } else {
        bookObj.forEach(function(element, index) {
            
            html += `<tr>
            <th scope="row">${index + 1}</th>
            <td>${element.bookName}</td>
            <td>${element.authorName}</td>
            <td>${element.type}</td>
            <th scope="col"> <button class="btn btn-primary"> Remove </button> </th>
            </tr>`;
        });
        Element = document.getElementById("tableBody");
        // console.log(typeof tableElement);
        Element.innerHTML = html;
    }
    html = "";
}

// .clear() method
Display.prototype.clear = function(){
    let form = document.getElementById("libraryForm");
    form.reset();
}
var display = new Display();    // Display object to access different display methods
display.add();
display.clear();

/*
    Book class with the property
    1) bookName = Name of the book
    2) authorName = Name of the author
    3) type = Type of book
*/ 
function Book(bookName, authorName, type){
    this.bookName = bookName;
    this.authorName = authorName;
    this.type = type;
}

let addBook = document.getElementById("addButton");
addBook.addEventListener("click", function (e){
    
    e.preventDefault();
    let bookName = document.getElementById("bookName").value;
    let authorName = document.getElementById("authorName").value;
    let type;
    let fiction = document.getElementById("Fiction");
    let programming = document.getElementById("Programming");
    let cooking = document.getElementById("Cooking");
    
    if (fiction.checked){
        type = fiction.value;
    } else if (programming.checked) {
        type = programming.value;
    }
    else if (cooking.checked) {
        type = cooking.value;
    }
    
    let book = new Book(bookName, authorName, type);
    bookObj.push(book);
    // console.log(typeof book)
    localStorage.setItem("books", JSON.stringify(bookObj));
    console.log(typeof bookObj);
    
    display.add();
    
    display.clear();
})

2个回答

这是因为当 bookObj 为空时,您会删除包含表格的 <div> (因此也删除了 tbody )。

然后,一旦您将书籍添加到 bookObj ,页面上就不再有表格可查找,因此 Elementnull

请考虑隐藏您不想出现的内容,而不是删除它。

var bookObj = [];
/*  Display Class with the following methods:
1) .add(book) => to add book(array of book objects) to the table element 
2) .clear => to clear the element from the text fields
*/
function Display() {}
// .add() method 
Display.prototype.add = function() {
/*  let bookElements = localStorage.getItem("books");
  if (bookElements === null) {
    bookObj = [];
  } else {
    bookObj = JSON.parse(bookElements);
    console.log(typeof bookObj);
  }
*/
  let html = "";
  if (bookObj.length === 0) {
    document.querySelector("#tableArea h1").style.display = "block";
    document.querySelector(".table").style.display = "none";
  } else {
    bookObj.forEach(function(element, index) {
      html += `<tr>
            <td scope="row">${index + 1}</td>
            <td>${element.bookName}</td>
            <td>${element.authorName}</td>
            <td>${element.type}</td>
            <td scope="col"> <button class="btn btn-primary"> Remove </button> </td>
            </tr>`;
    });

    document.getElementById("tableBody").innerHTML = html;
    document.querySelector("#tableArea h1").style.display = "none";
    document.querySelector(".table").style.display = "block";

  }
  html = "";
}

// .clear() method
Display.prototype.clear = function() {
  let form = document.getElementById("libraryForm");
  form.reset();
}
var display = new Display(); // Display object to access different display methods
display.add();
display.clear();

/*
    Book class with the property
    1) bookName = Name of the book
    2) authorName = Name of the author
    3) type = Type of book
*/
function Book(bookName, authorName, type) {
  this.bookName = bookName;
  this.authorName = authorName;
  this.type = type;
}

let addBook = document.getElementById("addButton");
addBook.addEventListener("click", function(e) {

  e.preventDefault();
  let bookName = document.getElementById("bookName").value;
  let authorName = document.getElementById("authorName").value;
  let type;
  let fiction = document.getElementById("Fiction");
  let programming = document.getElementById("Programming");
  let cooking = document.getElementById("Cooking");

  if (fiction.checked) {
    type = fiction.value;
  } else if (programming.checked) {
    type = programming.value;
  } else if (cooking.checked) {
    type = cooking.value;
  }

  let book = new Book(bookName, authorName, type);
  bookObj.push(book);
  // console.log(typeof book)
  //localStorage.setItem("books", JSON.stringify(bookObj));
  console.log(typeof bookObj);

  display.add();

  display.clear();
})
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Reading</title>

  <!-- CSS of the bootstrap  -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-zCbKRCUGaJDkqS1kPbPd7TveP5iyJE0EjAuZQTgFLD2ylzuqKfdKlfG/eSrtxUkn" crossorigin="anonymous">

  <!-- Custom CSS  -->
  <link rel="stylesheet" href="CSS/style.css">

  <!-- Google Fonts  -->
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Leckerli+One&display=swap" rel="stylesheet">

  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Serif:wght@400;700&display=swap" rel="stylesheet">

  <!-- Fontawesome cdn  -->
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css" integrity="sha384-DyZ88mC6Up2uqS4h/KRgHuoeGwBcD4Ng9SiP4dIRy0EXTlnuz47vAwmeGwVChigm" crossorigin="anonymous">

</head>

<body>

  <!-- Navbar Code  -->
  <nav class="navbar navbar-expand-lg navbar-dark bg-dark">

    <a href="#" class="navbar-brand navbar-expand-lg navbar-dark bg">READINGS</a>

    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarTogglerDemo01" aria-controls="navbarTogglerDemo01" aria-expanded="false" aria-label="Toggle navigation">
            <span class="navbar-toggler-icon"></span>
        </button>

    <div id="navbarTogglerDemo01" class="collapse navbar-collapse">
      <ul class="navbar-nav mr-auto">
        <li class="nav-item"> <a href="#" class="nav-links">Home</a></li>
      </ul>
    </div>
  </nav>

  <!-- library detail code starts  -->
  <div class="container-fluid form-section">
    <h1>My Reading Library</h1>

    <!-- Form section  -->
    <div class="container form-holder-div">

      <form id="libraryForm">
        <div class="form-group row">
          <label for="bookName" class="col-sm-2 col-form-label">Book Name</label>
          <div class="col-sm-10">
            <input type="text" class="form-control" id="bookName">
          </div>
        </div>
        <div class="form-group row">
          <label for="AuthorName" class="col-sm-2 col-form-label">Author of the book</label>
          <div class="col-sm-10">
            <input type="text" class="form-control" id="authorName">
          </div>
        </div>
        <fieldset class="form-group row">
          <legend class="col-form-label col-sm-2 float-sm-left pt-0">Type</legend>
          <div class="col-sm-10">
            <div class="form-check">
              <input class="form-check-input" type="radio" name="bookType" id="Fiction" value="fiction" checked>
              <label class="form-check-label" for="fiction">
                                Fiction
                            </label>
            </div>
            <div class="form-check">
              <input class="form-check-input" type="radio" name="bookType" id="Programming" value="programming">
              <label class="form-check-label" for="Programming">
                                Programming
                            </label>
            </div>
            <div class="form-check">
              <input class="form-check-input" type="radio" name="bookType" id="Cooking" value="cooking">
              <label class="form-check-label" for="Cooking">
                                Cooking
                            </label>
            </div>
          </div>
        </fieldset>
        <div class="form-group row">
          <div class="col-sm-10">
            <button type="submit" class="btn btn-primary" style="font-weight: 700;" id="addButton">Add Book</button>
          </div>
        </div>
      </form>
    </div>
  </div>

  <!-- table section  -->
  <div class="container-fluid table-section" id="tableArea">
  <h1>Please add some content from above section</h1>
    <table class="table">
      <thead class="thead-dark">
        <tr>
          <th scope="col">#</th>
          <th scope="col">Book Name</th>
          <th scope="col">Author Name</th>
          <th scope="col">Type</th>
          <th scope="col">Operation</th>
        </tr>
      </thead>

      <tbody id="tableBody">

      </tbody>
    </table>
  </div>

  <div class="footer-section">
    <h1><i class="far fa-copyright"> </i> Made with <i class="far fa-laugh-wink"></i> by TheNullPerson</h1>
  </div>

  <!-- This is the bootstrap javaScript -->
  <script src="javascript/index2.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous"></script>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.min.js" integrity="sha384-VHvPCCyXqtD5DqJeNxl2dtTyhF78xXNXdkwX1CZeRusQfRKp+tA7hAShOK/B/fQ2" crossorigin="anonymous"></script>
</body>

</html>
Randy Casburn
2021-11-07

您的代码没有问题,运行良好,但您看不到表格的原因是您为 Element 标识符分配了两个不同的值。在执行 javascript执行上下文 中,操作从 topbottom 完成。您的代码在 if 条件 中为 Element 标识符分配值,之后元素从执行上下文中删除。

if 语句 中删除 Element 标识符 的第一个分配后,您的 javascript 代码应如下所示。

var bookObj = [];
   /*  Display Class with the following methods:
   1) .add(book) => to add book(array of book objects) to the table element 
   2) .clear => to clear the element from the text fields*/

   function Display() {
   }
  // .add() method 

   Display.prototype.add = function () {
   let bookElements = localStorage.getItem("books");
   if (bookElements === null) {
    bookObj = [];
  } else {
    bookObj = JSON.parse(bookElements);
    console.log(typeof bookObj);
}

console.log(bookObj);
let html = "";
let Element;
if (bookObj.length === 0) {
    html = "<h1>Please add some content from above section</h1>";
    Element.innerHTML = html;
} else {
    bookObj.forEach(function(element, index) {
        
        html += `<tr>
        <th scope="row">${index + 1}</th>
        <td>${element.bookName}</td>
        <td>${element.authorName}</td>
        <td>${element.type}</td>
        <th scope="col"> <button class="btn btn-primary"> Remove </button> </th>
        </tr>`;
    });
    Element = document.getElementById("tableBody");
    // console.log(typeof tableElement);
    Element.innerHTML = html;
}
html = "";
}

  // .clear() method
  Display.prototype.clear = function(){
let form = document.getElementById("libraryForm");
form.reset();
}
var display = new Display();    // Display object to access different display methods
display.add();
display.clear();

/*
Book class with the property
1) bookName = Name of the book
2) authorName = Name of the author
3) type = Type of book */ 
 function Book(bookName, authorName, type){
this.bookName = bookName;
this.authorName = authorName;
this.type = type;
}

let addBook = document.getElementById("addButton");
addBook.addEventListener("click", function (e){

e.preventDefault();
let bookName = document.getElementById("bookName").value;
let authorName = document.getElementById("authorName").value;
let type;
let fiction = document.getElementById("Fiction");
let programming = document.getElementById("Programming");
let cooking = document.getElementById("Cooking");

if (fiction.checked){
    type = fiction.value;
} else if (programming.checked) {
    type = programming.value;
}
else if (cooking.checked) {
    type = cooking.value;
}

let book = new Book(bookName, authorName, type);
bookObj.push(book);
// console.log(typeof book)
localStorage.setItem("books", JSON.stringify(bookObj));
console.log(typeof bookObj);

display.add();

display.clear();
})

它可以正常工作并在 UI 上显示表格。

Dev Enock
2021-11-07