首页 > 解决方案 > Javascript dynamic button to delete item by id and delete himself (infinite loop)

问题描述

I am trying to push a ingredient to a list of array. This ingredient is an object and has its id from uuid or any library and an ingredient value of whatever the user types on the input.

I wrote the simplest example of it in a single function so its clear to understand the core of my doubt.

How can I delete the item by id and re-render, if the button is part of the renderization.

I could create a render function and invoke it inside the remove button. The problem is that the button would be part of that function.

Code

let ingredients = []

document.querySelector('#ingredients-input').addEventListener('change', (e) => {
  e.preventDefault()

  const id = uuid()

  ingredients.push({
    id: id,
    title: e.target.value
  })

  const ingredientUl = document.createElement('p')
  const removeButton = document.createElement('button')

  ingredientUl.textContent = e.target.value
  removeButton.textContent = 'remove'

  document.querySelector('#ingredients').append(ingredientUl, removeButton)

  removeButton.addEventListener('click', (e) => {
    const ingredientIndex = ingredients.findIndex(el => el.id === id)
    ingredients.splice(ingredientIndex, 1)
  })
})
<div id="ingredients"></div>
<input id="ingredients-input">

CodePen: https://codepen.io/notnishi/pen/QWyPdLL

Any help would be appreciated.

标签: javascript

解决方案


Instead of re rendering, you can delete the p tag and the remove button from#ingredients. Deleting only the specific elements from DOM is much more efficient than rerendering the whole ingredients list for just one change.

The remove button can be removed by using ChildNode.remove() and for deleting the ingredientUl, we can iterate over the child list of #ingredients and find the item to removed first and then delete it using Node.removeChild()

let ingredients = [];
const ingredientsNodeList = document.querySelector("#ingredients");

document.querySelector("#ingredients-input").addEventListener("change", (e) => {
  e.preventDefault();

  const id = uuid();

  ingredients.push({
    id: id,
    title: e.target.value,
  });

  const ingredientUl = document.createElement("p");
  const removeButton = document.createElement("button");

  ingredientUl.textContent = e.target.value;
  ingredientUl.id = id;
  e.target.value = ""; // Clearing the input after entering it to ingredients list
  removeButton.textContent = "remove";

  ingredientsNodeList.append(ingredientUl, removeButton);

  removeButton.addEventListener("click", (e) => {
    const ingredientIndex = ingredients.findIndex((el) => el.id === id);
    ingredients.splice(ingredientIndex, 1);

    const itemToDelete = [...ingredientsNodeList.children].find(el => el.id === id);
    ingredientsNodeList.removeChild(itemToDelete); // Removing ingredientUl
    e.target.remove(); // Deleting removeButton
  });
});

推荐阅读