删除动态创建的表单元素
Deleting dynamically created form elements
我一直在尝试制作一个动态表单,以便用户可以在他们提交的表单中添加一系列成分。我能够动态添加输入元素,但也想动态删除它们。我正在尝试使用基本 javascript 而不是 jquery 来完成所有这些工作。我 运行 的问题是,如果我将我的删除按钮片段放在 addBtn 单击事件中,我只能删除我选择的一项。如果我尝试将片段放在单击事件之外,我将无法通过 querySelectorAll 获取我想要的元素数组,因为查询是在 addBtn 事件侦听器关闭之前和元素创建之前进行的。提前致谢!
const ingredients = () => {
const container = document.querySelector(".show-ingredients");
const addBtn = document.querySelector(".add-ingredient");
const newIngredient = document.querySelector("#input-ingredients");
let ingredients = [];
newIngredient.required = true;
addBtn.addEventListener("click", async() => {
newIngredient.required = false;
ingredients.push(`
<div class="ingredient-container">
<input class='ingredient' type="text" value='${newIngredient.value}' required >
<div class="controls delete">
<a class="delete-ingredient">
<span class="ingredient-bar"></span>
</a>
</div>
</div>`);
container.innerHTML = ingredients.join("");
newIngredient.value = "";
});
var deleteBtn = document.querySelectorAll(".delete-ingredient");
console.log(deleteBtn);
for (let i = 0; i < deleteBtn.length; i++) {
deleteBtn[i].addEventListener("click", async() => {
console.log(i);
// ingredients.splice(i, 1);
// container.innerHTML = ingredients.join('');
});
}
if (ingredients.length == 0) {
newIngredient.required = true;
}
};
ingredients();
.form-container {
display: flex;
text-align: center;
flex-direction: column;
text-align: center;
justify-content: center;
align-items: center;
transition: all 0.5s ease-in-out;
}
.form-container input {
width: 400px;
max-width: 100%;
height: 40px;
padding-left: 10px;
margin-bottom: 5px;
}
/* Add/delete ingredient */
.ingredient-wrapper {
width: 400px;
max-width: 100%;
display: flex;
flex-direction: column;
}
.ingredient-container {
display: flex;
align-items: center;
justify-content: space-between;
height: 40px;
width: 400px;
max-width: 100%;
border: 1px solid grey;
margin-bottom: 5px;
}
.controls,
.controls.delete {
background-color: green;
height: 100%;
width: 28px;
padding-left: 1px;
}
.controls.delete {
background-color: red;
}
.ingredient {
margin-bottom: 0px;
width: 100%;
height: 100%;
background: none;
}
.add-ingredient,
.delete-ingredient {
width: 28px;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
transition: 0.5s ease-in-out;
cursor: pointer;
}
.ingredient-bar::before {
content: "";
background-color: white;
display: block;
height: 2px;
width: 13px;
transform: rotate(90deg);
}
.ingredient-bar {
background-color: white;
height: 2px;
width: 13px;
}
.delete-ingredient {
background-color: red;
}
.delete-ingredient .ingredient-bar::before {
display: none;
}
<form action="" class="form-container" id="wrapper">
<input type="text" placeholder="What's cookin?" id="input-title" style="margin-top: 20px;" required>
<div class="ingredient-wrapper">
<div class="ingredient-container">
<input type="text" placeholder="Ingredients" id="input-ingredients" style="border: none; margin-bottom: 0px; width: 400px;max-width:100%; height: 100%;">
<div class="controls">
<a class="add-ingredient">
<span class="ingredient-bar"></span>
</a>
</div>
</div>
<div class="show-ingredients"></div>
</div>
<input type="text" placeholder="Description/Instructions" id="input-description" required>
<button type="submit" class="add-btn">Add post</button>
</form>
Codepen 示例:https://codepen.io/benleem/pen/gOxgXWL(css 乱七八糟,但功能相同)
您应该能够通过将 .delete-ingredient
selector 和 addEventListener
移动到一个单独的函数中来获得所需的结果。
这是一个片段,它记录了 deletBtn
数组中的位置。我没有更改 HTML 或 CSS。我要补充的另一个小注意事项是成分数组没有正确连接到删除按钮,因为您每次都重新声明该数组(全局数组与本地数组)。但是,您实际上并不需要该数组,因为您可以使用 deleteBtn[i]
select 特定元素,然后可以使用 JavaScript .removeChild
功能将其删除。
const ingredients = () => {
const container = document.querySelector(".show-ingredients");
const addBtn = document.querySelector(".add-ingredient");
const newIngredient = document.querySelector("#input-ingredients");
let ingredients = [];
newIngredient.required = true;
addBtn.addEventListener("click", async () => {
newIngredient.required = false;
ingredients.push(`
<div class="ingredient-container">
<input class='ingredient' type="text" value='${newIngredient.value}' required >
<div class="controls delete">
<a class="delete-ingredient">
<span class="ingredient-bar"></span>
</a>
</div>
</div>`);
container.innerHTML = ingredients.join("");
newIngredient.value = "";
deleteIngredient(ingredients, container);
});
if (ingredients.length == 0) {
newIngredient.required = true;
}
};
const deleteIngredient = (list, wrapper) =>{
let ingredients = list;
let container = wrapper;
var deleteBtn = document.querySelectorAll('.delete-ingredient');
for (let i = 0; i < ingredients.length; i++) {
deleteBtn[i].addEventListener('click', async () =>{
console.log(i);
ingredients.splice(i, 1);
container.innerHTML = ingredients.join('');
deleteIngredient(ingredients, container);
});
}
}
ingredients();
.form-container {
display: flex;
text-align: center;
flex-direction: column;
text-align: center;
justify-content: center;
align-items: center;
transition: all 0.5s ease-in-out;
}
.form-container input {
width: 400px;
max-width: 100%;
height: 40px;
padding-left: 10px;
margin-bottom: 5px;
}
/* Add/delete ingredient */
.ingredient-wrapper {
width: 400px;
max-width: 100%;
display: flex;
flex-direction: column;
}
.ingredient-container {
display: flex;
align-items: center;
justify-content: space-between;
height: 40px;
width: 400px;
max-width: 100%;
border: 1px solid grey;
margin-bottom: 5px;
}
.controls,
.controls.delete {
background-color: green;
height: 100%;
width: 28px;
padding-left: 1px;
}
.controls.delete {
background-color: red;
}
.ingredient {
margin-bottom: 0px;
width: 100%;
height: 100%;
background: none;
}
.add-ingredient,
.delete-ingredient {
width: 28px;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
transition: 0.5s ease-in-out;
cursor: pointer;
}
.ingredient-bar::before {
content: "";
background-color: white;
display: block;
height: 2px;
width: 13px;
transform: rotate(90deg);
}
.ingredient-bar {
background-color: white;
height: 2px;
width: 13px;
}
.delete-ingredient {
background-color: red;
}
.delete-ingredient .ingredient-bar::before {
display: none;
}
<form action="" class="form-container" id="wrapper">
<input type="text" placeholder="What's cookin?" id="input-title" style="margin-top: 20px;" required>
<div class="ingredient-wrapper">
<div class="ingredient-container">
<input type="text" placeholder="Ingredients" id="input-ingredients" style="border: none; margin-bottom: 0px; width: 400px;max-width:100%; height: 100%;">
<div class="controls">
<a class="add-ingredient">
<span class="ingredient-bar"></span>
</a>
</div>
</div>
<div class="show-ingredients"></div>
</div>
<input type="text" placeholder="Description/Instructions" id="input-description" required>
<button type="submit" class="add-btn">Add post</button>
</form>
我一直在尝试制作一个动态表单,以便用户可以在他们提交的表单中添加一系列成分。我能够动态添加输入元素,但也想动态删除它们。我正在尝试使用基本 javascript 而不是 jquery 来完成所有这些工作。我 运行 的问题是,如果我将我的删除按钮片段放在 addBtn 单击事件中,我只能删除我选择的一项。如果我尝试将片段放在单击事件之外,我将无法通过 querySelectorAll 获取我想要的元素数组,因为查询是在 addBtn 事件侦听器关闭之前和元素创建之前进行的。提前致谢!
const ingredients = () => {
const container = document.querySelector(".show-ingredients");
const addBtn = document.querySelector(".add-ingredient");
const newIngredient = document.querySelector("#input-ingredients");
let ingredients = [];
newIngredient.required = true;
addBtn.addEventListener("click", async() => {
newIngredient.required = false;
ingredients.push(`
<div class="ingredient-container">
<input class='ingredient' type="text" value='${newIngredient.value}' required >
<div class="controls delete">
<a class="delete-ingredient">
<span class="ingredient-bar"></span>
</a>
</div>
</div>`);
container.innerHTML = ingredients.join("");
newIngredient.value = "";
});
var deleteBtn = document.querySelectorAll(".delete-ingredient");
console.log(deleteBtn);
for (let i = 0; i < deleteBtn.length; i++) {
deleteBtn[i].addEventListener("click", async() => {
console.log(i);
// ingredients.splice(i, 1);
// container.innerHTML = ingredients.join('');
});
}
if (ingredients.length == 0) {
newIngredient.required = true;
}
};
ingredients();
.form-container {
display: flex;
text-align: center;
flex-direction: column;
text-align: center;
justify-content: center;
align-items: center;
transition: all 0.5s ease-in-out;
}
.form-container input {
width: 400px;
max-width: 100%;
height: 40px;
padding-left: 10px;
margin-bottom: 5px;
}
/* Add/delete ingredient */
.ingredient-wrapper {
width: 400px;
max-width: 100%;
display: flex;
flex-direction: column;
}
.ingredient-container {
display: flex;
align-items: center;
justify-content: space-between;
height: 40px;
width: 400px;
max-width: 100%;
border: 1px solid grey;
margin-bottom: 5px;
}
.controls,
.controls.delete {
background-color: green;
height: 100%;
width: 28px;
padding-left: 1px;
}
.controls.delete {
background-color: red;
}
.ingredient {
margin-bottom: 0px;
width: 100%;
height: 100%;
background: none;
}
.add-ingredient,
.delete-ingredient {
width: 28px;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
transition: 0.5s ease-in-out;
cursor: pointer;
}
.ingredient-bar::before {
content: "";
background-color: white;
display: block;
height: 2px;
width: 13px;
transform: rotate(90deg);
}
.ingredient-bar {
background-color: white;
height: 2px;
width: 13px;
}
.delete-ingredient {
background-color: red;
}
.delete-ingredient .ingredient-bar::before {
display: none;
}
<form action="" class="form-container" id="wrapper">
<input type="text" placeholder="What's cookin?" id="input-title" style="margin-top: 20px;" required>
<div class="ingredient-wrapper">
<div class="ingredient-container">
<input type="text" placeholder="Ingredients" id="input-ingredients" style="border: none; margin-bottom: 0px; width: 400px;max-width:100%; height: 100%;">
<div class="controls">
<a class="add-ingredient">
<span class="ingredient-bar"></span>
</a>
</div>
</div>
<div class="show-ingredients"></div>
</div>
<input type="text" placeholder="Description/Instructions" id="input-description" required>
<button type="submit" class="add-btn">Add post</button>
</form>
Codepen 示例:https://codepen.io/benleem/pen/gOxgXWL(css 乱七八糟,但功能相同)
您应该能够通过将 .delete-ingredient
selector 和 addEventListener
移动到一个单独的函数中来获得所需的结果。
这是一个片段,它记录了 deletBtn
数组中的位置。我没有更改 HTML 或 CSS。我要补充的另一个小注意事项是成分数组没有正确连接到删除按钮,因为您每次都重新声明该数组(全局数组与本地数组)。但是,您实际上并不需要该数组,因为您可以使用 deleteBtn[i]
select 特定元素,然后可以使用 JavaScript .removeChild
功能将其删除。
const ingredients = () => {
const container = document.querySelector(".show-ingredients");
const addBtn = document.querySelector(".add-ingredient");
const newIngredient = document.querySelector("#input-ingredients");
let ingredients = [];
newIngredient.required = true;
addBtn.addEventListener("click", async () => {
newIngredient.required = false;
ingredients.push(`
<div class="ingredient-container">
<input class='ingredient' type="text" value='${newIngredient.value}' required >
<div class="controls delete">
<a class="delete-ingredient">
<span class="ingredient-bar"></span>
</a>
</div>
</div>`);
container.innerHTML = ingredients.join("");
newIngredient.value = "";
deleteIngredient(ingredients, container);
});
if (ingredients.length == 0) {
newIngredient.required = true;
}
};
const deleteIngredient = (list, wrapper) =>{
let ingredients = list;
let container = wrapper;
var deleteBtn = document.querySelectorAll('.delete-ingredient');
for (let i = 0; i < ingredients.length; i++) {
deleteBtn[i].addEventListener('click', async () =>{
console.log(i);
ingredients.splice(i, 1);
container.innerHTML = ingredients.join('');
deleteIngredient(ingredients, container);
});
}
}
ingredients();
.form-container {
display: flex;
text-align: center;
flex-direction: column;
text-align: center;
justify-content: center;
align-items: center;
transition: all 0.5s ease-in-out;
}
.form-container input {
width: 400px;
max-width: 100%;
height: 40px;
padding-left: 10px;
margin-bottom: 5px;
}
/* Add/delete ingredient */
.ingredient-wrapper {
width: 400px;
max-width: 100%;
display: flex;
flex-direction: column;
}
.ingredient-container {
display: flex;
align-items: center;
justify-content: space-between;
height: 40px;
width: 400px;
max-width: 100%;
border: 1px solid grey;
margin-bottom: 5px;
}
.controls,
.controls.delete {
background-color: green;
height: 100%;
width: 28px;
padding-left: 1px;
}
.controls.delete {
background-color: red;
}
.ingredient {
margin-bottom: 0px;
width: 100%;
height: 100%;
background: none;
}
.add-ingredient,
.delete-ingredient {
width: 28px;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
transition: 0.5s ease-in-out;
cursor: pointer;
}
.ingredient-bar::before {
content: "";
background-color: white;
display: block;
height: 2px;
width: 13px;
transform: rotate(90deg);
}
.ingredient-bar {
background-color: white;
height: 2px;
width: 13px;
}
.delete-ingredient {
background-color: red;
}
.delete-ingredient .ingredient-bar::before {
display: none;
}
<form action="" class="form-container" id="wrapper">
<input type="text" placeholder="What's cookin?" id="input-title" style="margin-top: 20px;" required>
<div class="ingredient-wrapper">
<div class="ingredient-container">
<input type="text" placeholder="Ingredients" id="input-ingredients" style="border: none; margin-bottom: 0px; width: 400px;max-width:100%; height: 100%;">
<div class="controls">
<a class="add-ingredient">
<span class="ingredient-bar"></span>
</a>
</div>
</div>
<div class="show-ingredients"></div>
</div>
<input type="text" placeholder="Description/Instructions" id="input-description" required>
<button type="submit" class="add-btn">Add post</button>
</form>