为什么要移除这样的子元素不起作用?

问题描述:

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>

+1

* MSG *引用您所创建的新文本节点,而不是之前的一个。第二种情况你可能会考虑'msg.parentNode.removeChild(msg)'。 – RobG

+0

他们怎么不一样?在第二个例子中,分配给变量'msg'的节点似乎与我使用'document.body.appendChild(msg);'创建的节点相同。 'console.log(msg === msg2);'比较返回'true'。为什么在第一个例子中不是这种情况?我是一个新手,我真的看不出有什么不同。 – Peter

+0

每当您离开年龄段时,都会调用txtAgeBlur函数。这意味着第二次调用它时,变量msg会像Rob提到的那样引用新的textnode,而不是dom中的文本节点。你的第二个例子工作的原因是因为变量msg仍然引用插入到dom中的节点。 –

每次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>

+0

非常感谢你们,所有的答案都有帮助。现在我明白了。 – Peter

+0

@Peter,我很乐意提供帮助。顺便说一句:每次调用“txtAgeBlur”时,你都不应该创建''。当你不打算插入时,没有理由创建''。如果可能,你应该避免在事件处理程序中做不必要的工作。因此,''应该只在'if(!messageInserted)'('你要把''追加到'target'的地方')中创建。这种方式只有在你实际使用它时才会被创建。 – Makyen

+0

感谢您的建议。对此,我真的非常感激。 – Peter