使用 javascript 通过 table 显示用户输入并使用按钮删除 <tr>

Using javascript to display user input with table and deleting a <tr> with button

我正在努力让它工作,想知道我是否正朝着正确的方向前进。

应该发生的是将两个输入字段添加到单击事件中。这部分已经完成并且工作正常。

将输入字段添加到 table 后应该发生的事情是,您可以使用创建 tr 时添加的按钮删除 tr。这是行不通的。我也想不通为什么当你点击删除按钮删除一个tr时页面会刷新,使用了preventDefault()。

let data             = [];
let speciesInput     = document.querySelector('#speciesInput')
let breedInput       = document.querySelector('#breedInput')
let messageBox       = document.getElementById("display");
const addProductBtn  = document.querySelector('#addValue')
let deleteProductBtn = document.getElementsByClassName('deleteProduct')
const deleteBtnArray = Array.from(deleteProductBtn)

addProductBtn.addEventListener('click', function (e) {
    e.preventDefault();

    let species, breed;
    species = speciesInput.value;
    breed   = breedInput.value;

    data.push({
        species: species,
        breed: breed,
    });
    clearAndShow();
})  

function clearAndShow() {
    // Clear our fields
    speciesInput.value   = "";
    breedInput.value     = "";
    messageBox.innerHTML = computeHTML();
}

function computeHTML() {
    let html = "<table>";
    data.forEach(function (item) {
        html += "<tr>";
        html += "<td>" + item.species + '&nbsp' + "</td>" 
        html += "<td>" + item.breed + "</td>"
        html += "<td>" + "<button class='deleteProduct' onclick='deleteProduct()'> &#8722; </button>" + "</td>"
        html += "</tr>"
        console.log(deleteBtnArray)
    });
    html += "</table>"
    return html;
}

function deleteProduct() {
    console.log(deleteBtnArray)
    deleteBtnArray.forEach((btn) => {
        btn.addEventListener('click', function (e) {
            e.preventDefault();
            console.log('Delete item')
            deleteItem() // Not made yet
        })
    })
}
deleteProduct()



document.querySelector('#productForm').addEventListener('submit', function (e) {
    e.preventDefault();
})
<!-- Add Product -->
<div class="">
  <div class="d-flex flex-column justify-content-center align-content-center">
    <div class="intro-wrapper">
      <h1 class="welcome-heading">Welcome <span class="brand-heading"></span><span class="brand-heading brand-heading-grey"></span></h1>
      <span class="intro-description">Set up your profile to begin interacting with the community.</span>
    </div>
    <span class="secondary-txt mt-5 mb-2">Add Your Product For Display</span>
    <form id="productForm" class="form d-flex flex-column align-items-center mt-2" action="">
      <div class="product-field-outter">
        <div class="form-field product-field-inner d-flex flex-column align-items-center">
          <div style="width: 100%!important;" class="form-field my-auto">
            <label for="species"></label>
            <input id="speciesInput" class="sign-up-inputs addProductInputs" type="text" placeholder="Species">
          </div>
          <div style="width: 100%!important;" class="form-field my-auto">
            <label for="breed"></label>
            <input id="breedInput" class="sign-up-inputs addProductInputs" type="text" placeholder="Breed">
          </div>
          <small></small>
          <button id="addValue" class="add-product-btn btn-active mt-4 ms-2">&#43;</button>
        </div>
      </div>
      <div id="display" class="output d-flex flex-column justify-content-center mt-5"></div>
      <!-- <ul id="list" class="productList justify-content-between"></ul> -->
      <button class="primary-btn continue-btn btn-active mt-4">Continue</button>
    </form>
    <button class="back-btn btn-active me-auto mt-4">Back</button>
  </div>
</div>
</div>

<!-- Add Product -->
<div class="">
    <div class="d-flex flex-column justify-content-center align-content-center">
        <div class="intro-wrapper">
            <h1 class="welcome-heading">Welcome<span class="brand-heading"></span><span class="brand-heading brand-heading-grey"></span></h1>
            <span class="intro-description">Set up your profile to begin interacting with the community.</span>
        </div>
        <span class="secondary-txt mt-5 mb-2">Add Your Product For Display</span>
        <form class="form d-flex flex-column align-items-center mt-2" action="">
            <div class="product-field-outter">
                <div class="form-field product-field-inner d-flex flex-column align-items-center">
                    <div style="width: 100%!important;" class="form-field my-auto">
                        <label for="species"></label>
                        <input id="speciesInput" class="sign-up-inputs addProductInputs" type="text" placeholder="Species">
                    </div>
                    <div style="width: 100%!important;" class="form-field my-auto">
                        <label for="breed"></label>
                        <input id="breedInput" class="sign-up-inputs addProductInputs" type="text" placeholder="Breed">
                    </div>
                    <small></small>
                    <button id="addValue" class="add-product-btn btn-active mt-4 ms-2">&#43;</button>
                </div>
            </div>
            <div id="display" class="output d-flex flex-column justify-content-center mt-5"></div>
            <!-- <ul id="list" class="productList justify-content-between"></ul> -->
            <button class="primary-btn continue-btn btn-active mt-4">Continue</button>
        </form>
        <button class="back-btn btn-active me-auto mt-4">Back</button>
        </div>
    </div>
</div>

Javascript

let data = [];
let speciesInput = document.querySelector('#speciesInput')
let breedInput = document.querySelector('#breedInput')

let messageBox = document.getElementById("display");
const addProductBtn = document.querySelector('#addValue')
let deleteProductBtn = document.getElementsByClassName('deleteProduct')
const deleteBtnArray = Array.from(deleteProductBtn)

addProductBtn.addEventListener('click', function (e) {
    e.preventDefault();

    let species, breed;
    species = speciesInput.value;
    breed = breedInput.value;

    data.push({
        species: species,
        breed: breed,
    });
    clearAndShow();
})  

function clearAndShow() {
    // Clear our fields
    speciesInput.value = "";
    breedInput.value = "";
    messageBox.innerHTML = computeHTML();
}

function computeHTML() {
    let html = "<table>";
    data.forEach(function (item) {
        html += "<tr>";
        html += "<td>" + item.species + '&nbsp' + "</td>" 
        html += "<td>" + item.breed + "</td>"
        html += "<td>" + "<button class='deleteProduct' onclick='deleteProduct()'> &#8722; </button>" + "</td>"
        html += "</tr>"
        console.log(deleteBtnArray)
    });
    html += "</table>"
    return html;
}

function deleteProduct() {
    console.log(deleteBtnArray)
    deleteBtnArray.forEach((btn) => {
        btn.addEventListener('click', function (e) {
            e.preventDefault();
            console.log('Delete item')
            deleteItem() // Not made yet
        })
    })
}
deleteProduct()

发生的事情不止一件事

  1. 仅当页面加载时,JS 代码顶部的变量才从文档对象中恢复元素。在 clearAndShow() 函数上附加 html 后,您不会更新它们(即 deleteBtnArray)。这就是当您单击 - 按钮时 deleteBtnArray 始终为空的原因。 避免这种情况的一种方法是在 deleteProduct 函数中收集元素。此外,您不需要使用 Array.from 转换为数组,因为 document.getElementsByClassName(...) 已经 returns 一个可迭代的集合。此外,使用“for of”比带回调的 forEach 可读性更好。

  2. 您使用此方法多次添加 deleteProduct(...) 函数,因为您使用 onclick='deleteProduct()'btn.addEventListener('click'...) 进行调用。之后,您还可以在 deleteProduct 函数声明后立即调用它。没必要。

  3. 如果你想删除整个 <tr>,有一种简单的方法可以用一个 id 引用每个 <tr> 并将其用作 [= 的参数18=] 函数,就像下面的例子一样

用这个替换你的整个javascript,并使用相同的HTML

let data = [];
var speciesInput = document.querySelector('#speciesInput')
var breedInput = document.querySelector('#breedInput')
var messageBox = document.getElementById("display");
var addProductBtn = document.querySelector('#addValue')

addProductBtn.addEventListener('click', function (e) {
  e.preventDefault();

  let species, breed;
  species = speciesInput.value;
  breed = breedInput.value;

  data.push({
    species: species,
    breed: breed,
  });
  clearAndShow();
})

function clearAndShow() {
  // Clear our fields
  speciesInput.value = "";
  breedInput.value = "";
  messageBox.innerHTML = computeHTML();
}

function computeHTML() {
  let html = "<table>";
  data.forEach(function (item, index) {
    html += "<tr id='line-" + index + "'>";
    html += "<td>" + item.species + '&nbsp' + "</td>"
    html += "<td>" + item.breed + "</td>"
    html += "<td>" + "<button onclick='deleteProduct(" + index + ")'> &#8722; </button>" + "</td>"
    html += "</tr>"
  });
  html += "</table>"
  return html;
}

function deleteProduct(removedIndex) {
  document.getElementById("line-" + removedIndex).remove()
  data = data.filter(function (item, index) { return index != removedIndex })
}

document.querySelector('#productForm').addEventListener('submit', function (e) {
  e.preventDefault();
})

奖金:

我建议你在字符串中写 html 时使用 ` 而不是 " 或 ',因为

  • 您可以使用 ${variableName}
  • 插入变量
  • 你可以换行
  • 您可以在由 `
  • 分隔的字符串中自由使用 ' 和 "
  • 你不需要使用很多 +=

我还建议您使用 .map( 而不是 .forEach(。这样事情就变得干净了。

用这段代码替换我之前展示的computeHTML()

function itemHtml(item, index) {
  return `<tr id="line-${index}">
    <td>${item.species}</td>
    <td>${item.breed}</td>
    <td><button onclick="deleteProduct(${index})"> &#8722; </button></td>
  </tr>`
}

function computeHTML() {
  return `<table>${data.map(itemHtml)}</table>`
}