为什么要移除这样的子元素不起作用?
问题描述:
txtAgeBlur
函数的最后一行有个问题。为什么我不能像这样删除子节点?为什么要移除这样的子元素不起作用?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Forms</title>
</head>
<body>
<form action="" name="form1">
<p>
Name
<input type="text" name="txtName">
</p>
<p>
Age
<input type="text" name="txtAge" size="3" maxlength="3"> \t
</p>
<p>
<input type="button" value="Check details" name="btnCheckForm">
</p>
</form>
<script>
var myForm = document.form1;
function btnCheckFormClick(e) {
var name = myForm.txtName.value;
var age = myForm.txtAge.value;
if (name === "" || age === "") {
alert("Please complete all of the form");
if (name === "")
myForm.txtName.focus();
else
myForm.txtAge.focus();
}
else
alert("Thanks for completing the form " + name);
}
var messageInserted = false;
function txtAgeBlur(e) {
//console.log(e.type);
var target = e.target;
var msg = document.createElement("span");
msg.id = "msg";
msg.appendChild(document.createTextNode("Please enter a valid age"));
if (isNaN(target.value)) {
if (!messageInserted) {
messageInserted = true;
target.parentElement.appendChild(msg);
}
target.focus();
target.select();
}
else if (messageInserted === true)
document.getElementsByTagName("p")[1].removeChild(msg); //problem
}
myForm.btnCheckForm.addEventListener("click", btnCheckFormClick);
myForm.txtAge.addEventListener("blur", txtAgeBlur);
</script>
</body>
</html>
然而,这将删除子元素没有任何问题。这和上面的例子有什么区别?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Forms</title>
</head>
<body>
<script>
var msg = document.createElement("span");
msg.appendChild(document.createTextNode("Please enter a valid age"));
document.body.appendChild(msg);
var msg2 = document.querySelector("span");
console.log(msg === msg2);
document.body.removeChild(msg);
</script>
</body>
</html>
答
每次txtAgeBlur
被调用,您创建您msg
引用新<span>
。当您尝试删除当前显示的消息时,msg
引用尚未插入的新的<span>
。您需要获取对当前显示消息的引用才能将其删除。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Forms</title>
</head>
<body>
<form action="" name="form1">
<p>
Name
<input type="text" name="txtName">
</p>
<p>
Age
<input type="text" name="txtAge" size="3" maxlength="3"> \t
</p>
<p>
<input type="button" value="Check details" name="btnCheckForm">
</p>
</form>
<script>
var myForm = document.form1;
function btnCheckFormClick(e) {
var name = myForm.txtName.value;
var age = myForm.txtAge.value;
if (name === "" || age === "") {
alert("Please complete all of the form");
if (name === "")
myForm.txtName.focus();
else
myForm.txtAge.focus();
}
else
alert("Thanks for completing the form " + name);
}
var messageInserted = false;
function txtAgeBlur(e) {
//console.log(e.type);
var target = e.target;
if (isNaN(target.value)) {
if (!messageInserted) {
//There is no reason to do the work of creating the <span> if you are not
// going to be inserting it. Thus, you should create it here, not
// every time you call txtAgeBlur.
var msg = document.createElement("span");
msg.id = "msg";
msg.appendChild(document.createTextNode("Please enter a valid age"));
messageInserted = true;
target.parentElement.appendChild(msg);
}
target.focus();
target.select();
} else if (messageInserted === true){
//When you get here, msg is a NEW span that has not been inserted. Thus,
// you do not remove the span that has never been inserted.
//document.getElementsByTagName("p")[1].removeChild(msg); //problem
//You need to get a reference to the span you have already inserted.
var currentMessage = document.getElementById('msg');
currentMessage.parentNode.removeChild(currentMessage);
//The user may change age back to NaN and need the message re-inserted.
messageInserted = false;
}
}
myForm.btnCheckForm.addEventListener("click", btnCheckFormClick);
myForm.txtAge.addEventListener("blur", txtAgeBlur);
</script>
</body>
</html>
* MSG *引用您所创建的新文本节点,而不是之前的一个。第二种情况你可能会考虑'msg.parentNode.removeChild(msg)'。 – RobG
他们怎么不一样?在第二个例子中,分配给变量'msg'的节点似乎与我使用'document.body.appendChild(msg);'创建的节点相同。 'console.log(msg === msg2);'比较返回'true'。为什么在第一个例子中不是这种情况?我是一个新手,我真的看不出有什么不同。 – Peter
每当您离开年龄段时,都会调用txtAgeBlur函数。这意味着第二次调用它时,变量msg会像Rob提到的那样引用新的textnode,而不是dom中的文本节点。你的第二个例子工作的原因是因为变量msg仍然引用插入到dom中的节点。 –