簡體   English   中英

為什么當我嘗試編輯它時該元素在表單中返回未定義,但在調試器和 console.log 中正確顯示?

[英]Why is this element returning undefined in the form when I attempt to edit it, but displaying correctly in debugger and console.log?

我不斷收到此錯誤:“無法讀取 HTMLDocument 中未定義的屬性 'textContent'”。 當 dogName、dogBreed 和 dogSex 並在“點擊”偵聽器中設置時會發生此錯誤。 我可以單擊按鈕並呈現信息,但是一旦單擊文本區域以編輯補丁請求的 dogName 等,就會發生此錯誤。 但是,如果我使用調試器或控制台日志,它會返回我想要的內容。 不確定是什么問題? 任何幫助將不勝感激,謝謝!

<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8" />
    <title>WKC Dog Show</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous" />
    <script src="./src/index.js"></script>
    <link rel="stylesheet" href="./assets/style.css" />
    <link href="https://fonts.googleapis.com/css?family=Kaushan+Script|Open+Sans" rel="stylesheet" />
  </head>
  <body>
    <div class='main flex'>
      <h1 class='padding margin'>Westminster Kennel Club Dog Show</h1>

      <div class="margin flex">
        <h4 class='center'>Edit Existing Dog</h4>
        <form id='dog-form' class="padding margin border-round border-grey">
          <input type="text" name="name" placeholder="dog's name" value="" />
          <input type="text" name="breed" placeholder="dog's breed" value="" />
          <input type="text" name="sex" placeholder="dog's sex" value="" />
          <input type="submit" value="Submit" />
        </form>
      </div>

      <div class="margin flex">
        <h4 class='center'>Registered Dogs</h4>
        <table class='margin' border="1" id='table'>
          <thead class='blue'>
            <tr class='padding'>
              <th class='padding center'>Name</th>
              <th class='padding center'>Breed</th>
              <th class='padding center'>Sex</th>
              <th class='padding center'>Edit Dog</th>
            </tr>
          </thead>
          <tbody id="table-body">
          </tbody>
        </table>
      </div>
    </div>
  </body>
</html>

document.addEventListener('DOMContentLoaded', () => {
    const dogsUrl = `http://localhost:3000/dogs`
    const table = document.querySelector('#table-body')


function getDogs(){
    fetch(dogsUrl)
    .then(response => response.json())
    .then(renderDogs)
} 


  const renderDogs = dogs => {      
    table.innerHTML = ''
        dogs.forEach(dog=> {
        const tableRow = document.createElement('tr')
        tableRow.innerHTML = `<td>${dog.name}</td>
        <td>${dog.breed}</td>
        <td>${dog.sex}</td>
        <td><button type="click">Edit this dog!</button></td>`
        tableRow.dataset.id = dog.id
    table.append(tableRow)
})}

document.addEventListener("click",function(e){

    const dogForm = document.getElementById('dog-form')

    const tableRow = e.target.parentElement.parentElement

    const dogInfo = tableRow.getElementsByTagName("td")

    const dogName=dogInfo[0].textContent
    const dogBreed=dogInfo[1].textContent
    const dogSex=dogInfo[2].textContent

    dogForm.name.value = dogName
    dogForm.breed.value = dogBreed
    dogForm.sex.value = dogSex
    dogForm.dataset.id = tableRow.dataset.id

})

document.addEventListener('submit', function(e){
    e.preventDefault()


    const dogForm = e.target
    const id = dogForm.dataset.id
    const name = dogForm.name.value
    const breed = dogForm.breed.value
    const sex = dogForm.sex.value

    fetch(`${dogsUrl}`/`${id}`, {
        method: 'PATCH',
        headers: { 
            "Content-Type": "application/json",
            "Accept": "application/json"
         },
        body: JSON.stringify({ name, breed, sex })
        })
        .then(response => response.json())
        .then(fetchDogs)
})

getDogs()

})

  1. 您在文檔上有一個單擊偵聽器,每次單擊任何內容都會執行該代碼。 我要做的第一件事是將事件偵聽器限制為您想要偵聽的元素——按鈕。 只需將 class 添加到編輯按鈕即可。
<button type="click" class="edit-dog">Edit this dog!</button>
  1. 現在我們必須在每個按鈕上添加事件監聽器,否則它只會將它添加到第一個按鈕。 制作一組按鈕並循環遍歷每個按鈕以添加事件偵聽器。

  2. 制作一個您調用的 function 來完成點擊發生時的所有工作copyDogData

  3. The event listener was being added before the renderDogs function had built the html, so place it inside the render dogs function after the forEach and your HTML will be built before you try to have event listeners being attached.

完成代碼:

document.addEventListener("DOMContentLoaded", () => {
  const dogsUrl = `http://localhost:3000/dogs`;
  const table = document.querySelector("#table-body");

  function getDogs() {
    fetch(dogsUrl)
      .then((response) => response.json())
      .then(renderDogs);
  }

  const renderDogs = (dogs) => {
    table.innerHTML = "";
    dogs.forEach((dog) => {
      const tableRow = document.createElement("tr");
      tableRow.innerHTML = `<td>${dog.name}</td>
        <td>${dog.breed}</td>
        <td>${dog.sex}</td>
        <td><button type="click" class="edit-dog">Edit this dog!</button></td>`;
      tableRow.dataset.id = dog.id;
      table.append(tableRow);
    });

    const buttons = document.querySelectorAll(".edit-dog");

    for (var button of buttons) {
      button.addEventListener("click", function (e) {
        copyDogData(e.target);
      });
    }
  };

  function copyDogData(target) {
    const dogForm = document.getElementById("dog-form");

    const tableRow = target.parentNode.parentNode;

    const dogInfo = tableRow.getElementsByTagName("td");

    const dogName = dogInfo[0].textContent;
    const dogBreed = dogInfo[1].textContent;
    const dogSex = dogInfo[2].textContent;

    dogForm.name.value = dogName;
    dogForm.breed.value = dogBreed;
    dogForm.sex.value = dogSex;
    dogForm.dataset.id = tableRow.dataset.id;
  }

  document.addEventListener("submit", function (e) {
    e.preventDefault();

    const dogForm = e.target;
    const id = dogForm.dataset.id;
    const name = dogForm.name.value;
    const breed = dogForm.breed.value;
    const sex = dogForm.sex.value;

    fetch(`${dogsUrl}` / `${id}`, {
      method: "PATCH",
      headers: {
        "Content-Type": "application/json",
        Accept: "application/json",
      },
      body: JSON.stringify({ name, breed, sex }),
    })
      .then((response) => response.json())
      .then(fetchDogs);
  });

  getDogs();
});

這是問題

const tableRow = e.target.parentElement.parentElement

它應該是

const tableRow = e.target.parentElement.parentElement.parentElement;

因為當您單擊input時,輸入的父級是formform具有div的父級,並且該 div 的父級包含table

div.main.flex < div.margin.flex < form < input

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM