删除 div 后,添加 div 不起作用。为什么?
我正在使用 HTML、CSS 和 JavaScript 制作一个费用跟踪器,我遇到了一个问题,当我第一次加载页面时,我可以添加任意数量的 div 项,但是当我删除其中一个(或多个)项后,添加按钮不再起作用。我在控制台中收到的错误是:
main.js:8 Uncaught TypeError: Cannot read properties of null (reading 'appendChild') at HTMLButtonElement.duplicate (main.js:8:25).
我有一个用于删除 div 的函数(在本例中,div 是列表中的费用项),称为 deleteItem(),另一个用于添加 div 的函数称为 duplicate()。我不确定发生了什么,但如果有人能帮忙,那就太好了。 我在 YouTube 上看到了一些使用 JQuery 的可能解决方案,但由于我仍在学习 JavaScript,所以我暂时不想涉及它。但是,如果解决方案需要 JQuery 或类似的东西,请告诉我。
document.getElementById('new-item-btn').onclick = duplicate;
var original = document.getElementById('expense-item');
function duplicate() {
var clone = original.cloneNode(true);
clone.id = "expense-item";
original.parentNode.appendChild(clone);
}
function deleteItem() {
var removeItem = document.getElementById('expense-item');
removeItem.remove();
}
<main id="main">
<div class="container" id="container">
<div class="expense-item" id="expense-item">
<button class="delete-btn" onclick="deleteItem()">Delete</button>
<div class="expense-inputs">
<label for="expense-name"></label>
<input type="text" placeholder="Expense Name" id="expense-name">
<label for="expense-category"></label>
<select name="expense-category" id="expense-category">
<option value="">Category</option>
<option value="groceries">Groceries</option>
<option value="housing">Housing</option>
<option value="utilities">Utilities</option>
</select>
<label for="expense-amount"></label>
<input type="text" id="expense-amount" name="expense-amount" placeholder="Amount">
</div>
</div>
</div>
<div class="info">
<div class="new-item">
<button class="new-item-btn" id="new-item-btn" onclick="duplicate()">New Item</button>
</div>
</div>
</main>
要使删除方法动态化并且无需 id 即可工作,您可以这样做:
function deleteItem(obj) { // <- obj refers to the clicked object because of `this` in onclick="deleteItem()"
var removeItem = obj.parentElement; // <- use parentElement to target the "<div class="expense-item" id="expense-item">"
removeItem.remove();
}
然后,您只需将
this
添加到
onclick="deleteItem()"
注意 我建议您在创建时仍将 id 更改为新内容,但这是删除方法的示例。
演示
document.getElementById('new-item-btn').onclick = duplicate;
var original = document.getElementById('expense-item');
function duplicate() {
var clone = original.cloneNode(true);
original.parentNode.appendChild(clone);
}
function deleteItem(obj) {
var removeItem = obj.parentElement;
removeItem.remove();
}
<main id="main">
<div class="container" id="container">
<div class="expense-item" id="expense-item">
<button class="delete-btn" onclick="deleteItem(this)">Delete</button>
<div class="expense-inputs">
<label for="expense-name"></label>
<input type="text" placeholder="Expense Name" id="expense-name">
<label for="expense-category"></label>
<select name="expense-category" id="expense-category">
<option value="">Category</option>
<option value="groceries">Groceries</option>
<option value="housing">Housing</option>
<option value="utilities">Utilities</option>
</select>
<label for="expense-amount"></label>
<input type="text" id="expense-amount" name="expense-amount" placeholder="Amount">
</div>
</div>
</div>
<div class="info">
<div class="new-item">
<button class="new-item-btn" id="new-item-btn" onclick="duplicate()">New Item</button>
</div>
</div>
</main>
在大多数情况下,您可以在创建动态内容时删除 ID,并使用其他方式识别 DOM 节点 - 例如将
querySelector
与
event.target
结合使用。检查
Event
以确定点击的来源可能是最可靠的方法。
动态添加的内容事先不知道 ID 或其他属性,因此通过将
event
作为参数提供给
deleteItem
方法,您可以识别从按钮到容器的新添加的内容并轻松将其删除。
document.querySelector('.new-item-btn').onclick = duplicate;
function duplicate() {
const original = document.querySelector('[data-id="expense-item"]');
original.parentNode.appendChild( original.cloneNode(true) );
}
function deleteItem(e) {
let item = e.target.closest('.expense-item');
if( document.querySelectorAll('.expense-item').length > 1 ){
item.parentNode.removeChild( item );
}
}
<main>
<div class="container">
<div class="expense-item" data-id="expense-item">
<button class="delete-btn" onclick="deleteItem(event)">Delete</button>
<div class="expense-inputs">
<label>
<input type="text" placeholder="Expense Name" />
</label>
<label>
<select name="expense-category" data-id="expense-category">
<option value="">Category</option>
<option value="groceries">Groceries</option>
<option value="housing">Housing</option>
<option value="utilities">Utilities</option>
</select>
</label>
<label>
<input type="text" name="expense-amount" placeholder="Amount" />
</label>
</div>
</div>
</div>
<div class="info">
<div class="new-item">
<button class="new-item-btn" data-id="new-item-btn" onclick="duplicate()">New Item</button>
</div>
</div>
</main>