javascript - button needs to be click twice for onclick to trigger

风格不统一 提交于 2019-12-12 11:33:21

问题


Why does my button need to be clicked twice for the onclick event to trigger? There're some other thread on stackoverflow with the same problem, but in all the thread i found, the original poster puts the event handler inside the function. It's not like that with my code.

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>

Script:

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

Demonstration: onclick-error


回答1:


The first "element" within the parentList is whitespace. You can see this by console logging the element within the event listener.

You therefore need to only filter out the li elements within the parent item.

document.getElementById("delete").onclick = function() {
    var listItems = document.querySelectorAll("#parentList > li");

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

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

You could also use parentList.firstElementChild instead of parentList.firstChild, which filters out any invalid nodes (whitespace).

An example of this

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

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

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




回答2:


There is nothing wrong with your click handler on the button. The problem is with the way you are removing the first child. If you add this small change to your function:

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

You will notice that the first click logs out some empty spaces with a line break. This appears to be an empty text node. The second click removes the first <li> and so on...




回答3:


With elementChild, you look for any child, including white spaces.

You could use parentList.firstElementChild instead to get the first child element.




回答4:


As you could see in following snippet, first child is string of new line and spaces:

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>

You could use firstElementChild property to get only the first child Element, like:

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>


来源:https://stackoverflow.com/questions/43636285/javascript-button-needs-to-be-click-twice-for-onclick-to-trigger

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!