我正在尝试删除特定的li元素,基于此元素单击了x按钮。目前,我有一个错误
“ bZMQWNZvyQeA:42未捕获的TypeError:无法在'Node'上执行'removeChild':参数1的类型不是'Node'。”
我知道这可能意味着参数为空,但这对我来说没有任何意义。 Chrome开发工具显示onClick属性正确执行removeItem,并将idName作为参数传递。这怎么不起作用?
var note = 0;
function saveInfo() {
var idName = "note" + note;
//assign text from input box to var text, and store in local storage
var input = document.getElementById('input').value;
var text = localStorage.setItem(note, input);
var list = document.createElement("li");
var node = document.createTextNode(input);
var removeBtn = document.createElement("button");
list.setAttribute("id", idName);
removeBtn.setAttribute("onClick", `removeItem(${idName})`);
removeBtn.innerHTML = "X";
list.appendChild(node);
list.appendChild(removeBtn);
document.getElementById("output").appendChild(list);
note += 1;
}
function removeItem(name) {
var parent = document.getElementById("output");
var child = document.getElementById(name);
parent.removeChild(child);
}
答案 0 :(得分:0)
问题是您传递给removeItem
的ID周围缺少引号:
removeBtn.setAttribute("onClick", `removeItem(${idName})`);
这应该是:
removeBtn.setAttribute("onClick", `removeItem('${idName}')`);
更好的做法是绑定单击处理程序,而不依赖于代码的字符串评估,也无需创建动态的id
属性值:
removeBtn.addEventListener("click", () => removeItem(list));
然后函数removeItem
应该期望节点本身,而不是id:
function removeItem(child) {
child.parentNode.removeChild(child);
}
您可以删除以下代码:
var idName = "note" + note;
list.setAttribute("id", idName);
答案 1 :(得分:0)
在我的评论中,我建议您听removeBtn
中的单击事件冒泡。在这种情况下,您所需要做的就是从代码中删除onclick
属性分配逻辑,而是为removeButton
提供一个可识别的属性,例如一个类。让我们给它一个delete-button
类:
var removeBtn = document.createElement("button");
removeBtn.classList.add('delete-button');
removeBtn.type = 'button';
removeBtn.innerHTML = 'X';
然后,您可以在#output
级别上监听click事件,该事件一定会在运行时出现。触发事件后,您只需检查事件目标是否具有可识别的属性,例如在我们的案例中是remove-button
类:
output.addEventListener('click', function(e) {
// GUARD: Do nothing if click event does not originate from delete button
if (!e.target.matches('.remove-button')) {
return;
}
// Delete parent node
e.target.closest('li').remove();
});
如果click事件不是由“删除”按钮引起的,我们只需return
,就什么也不要做。否则,我们知道已经单击了该按钮,然后可以使用Element.closest()
,即.closest('li')
来检索最近的<li>
父节点并将其删除。
如果绝对必须支持IE11(反过来,它不支持Element.closest()
),则也可以使用Node.parentNode
来访问和删除<li>
元素,前提是您要删除按钮是<li>
元素的直接子元素:
// Delete parent node
e.target.parentNode.remove();
请参见下面的概念验证:
var rows = 10;
var output = document.getElementById('output');
for (var i = 0; i < rows; i++) {
var list = document.createElement('li');
var node = document.createTextNode('Testing. Row #' + i);
var removeBtn = document.createElement("button");
removeBtn.classList.add('remove-button');
removeBtn.type = 'button';
removeBtn.innerHTML = 'X';
list.appendChild(node);
list.appendChild(removeBtn);
output.appendChild(list);
}
output.addEventListener('click', function(e) {
// GUARD: Do nothing if click event does not originate from delete button
if (!e.target.matches('.remove-button')) {
return;
}
e.target.closest('li').remove();
});
<ul id="output"></ul>