JavaScript - 按钮需要点击两次才能触发onclick事件

7

我的按钮为什么需要点击两次才能触发onclick事件?在stackoverflow上有一些其他的帖子也遇到了相同的问题,但是在所有我找到的帖子中,原始帖子都将事件处理程序放置在函数内部。但是我的代码不是这样的。

Html

<body>
    <ul id="parentList">
        <li>First child</li>
        <li>Second child</li>
        <li>Third child</li>
        <li>Forth child</li>
        <li>Fifth child</li>
    </ul>
    <button type="button" id="delete">Delete first child</button>
</body>

脚本:

var parentList = document.getElementById("parentList");
document.getElementById("delete").onclick = function() {
    parentList.removeChild(parentList.firstChild);
};

演示: 单击错误

你尝试在函数中定义parentList了吗? - Felix Haeberle
@FelixHäberle 你的意思是什么??需要点击两次,但是<li>子元素确实被删除了,所以浏览器必须识别parentList,不是吗? - Nhu Thai Sanh Nguyen
我认为parentList在第一次点击时已经超出了作用域。将你的第一行js代码复制到函数中。 - Felix Haeberle
@FelixHäberle 你说的 parentList 超出了作用域是什么意思? - evolutionxbox
为什么不使用 firstElementChild 呢?这样你就可以确保删除的是一个元素节点,而不是文本节点。https://developer.mozilla.org/docs/Web/API/ParentNode/firstElementChild - evolutionxbox
4个回答

7
父级列表中的第一个“元素”是空格。您可以通过在事件侦听器中记录元素来查看此内容。

whitespace example

因此,您只需要筛选出父项中的 li 元素。
document.getElementById("delete").onclick = function() {
    var listItems = document.querySelectorAll("#parentList > li");

    if (listItems.length > 0) {
        listItems[0].remove();
    }
};

https://jsfiddle.net/ofLvac32/13/

您也可以使用parentList.firstElementChild代替parentList.firstChild,这将过滤掉任何无效节点(空格)。

以下是一个示例

var parentList = document.getElementById("parentList");

document.getElementById("delete").onclick = function() {
    parentList.removeChild(parentList.firstElementChild);
};

https://jsfiddle.net/ofLvac32/37/


1
还有firstElementChild方法。另外请注意,childNode.remove()不支持IE。 - evolutionxbox
谢谢您的建议!我会将其作为另一种解决方案添加到答案中!我之前不知道这个。 - Toby Mellor

1
使用elementChild,您可以查找任何子元素,包括空格。
相反,您可以使用parentList.firstElementChild来获取第一个子元素

0

如下代码片段所示,第一个子元素是换行符和空格的字符串:

function loaded(){
  document.getElementById("parentList");
  var firstChild = parentList.firstChild;
  console.log("First child: \"" + firstChild.data + "\"");
}
<body onload="javascript:loaded()">
 <ul id="parentList">
  <li>First child</li>
  <li>Second child</li>
  <li>Third child</li>
  <li>Forth child</li>
  <li>Fifth child</li>
 </ul>
</body>

你可以使用firstElementChild属性来获取第一个子元素,例如:

var parentList = document.getElementById("parentList");
document.getElementById("delete").onclick = function() {  parentList.removeChild(parentList.firstElementChild);
};
<ul id="parentList">
    <li>First child</li>
    <li>Second child</li>
    <li>Third child</li>
    <li>Forth child</li>
    <li>Fifth child</li>
</ul>
<button type="button" id="delete">Delete first child</button>


0

您的按钮点击处理程序没有问题。问题出在您删除第一个子元素的方式上。如果您在函数中添加这个小改变:

var parentList = document.getElementById("parentList");
    document.getElementById("delete").onclick = function() {
    console.log(parentList.removeChild(parentList.firstChild));
};

你会注意到第一次点击会记录一些带有换行符的空白空间。这似乎是一个空文本节点。第二次点击会删除第一个<li>,以此类推...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接