Javascript 从DOM中删除元素(如果存在)的最佳方法

Javascript 从DOM中删除元素(如果存在)的最佳方法,javascript,validation,dom,Javascript,Validation,Dom,我最近又回到了Javascript,我创建了这个简单的表单验证作为实践。我想知道从逻辑上讲,做某事最好的方式是什么。请看下面的代码: var regName = /^[A-Za-z]+$/; var regEmail = /^[A-Za-z]+$/; var regUserName = /^[A-Za-z]+$/; var regPassword = /^[A-Za-z]+$/; //span tags multiply when you keep hitting the submit but

我最近又回到了Javascript,我创建了这个简单的表单验证作为实践。我想知道从逻辑上讲,做某事最好的方式是什么。请看下面的代码:

var regName = /^[A-Za-z]+$/;
var regEmail = /^[A-Za-z]+$/;
var regUserName = /^[A-Za-z]+$/;
var regPassword = /^[A-Za-z]+$/;

//span tags multiply when you keep hitting the submit button. .textContent doesn't seem to work, and even if it did it's kind of a cheap work around because the tags will still be there, you just wont see them. I need to check if the tag exists (before the if statement) and if it does, remove it.

var validate = {
  validateName: function() {
    var fName = document.getElementById('fName');
    var nameContainer = document.querySelector('#nameContainer');
    var infoSpan = document.createElement('span');

    nameContainer.appendChild(infoSpan);
    fName.classList.remove('errorBorder');

    if (fName.value.match(regName)) {
      console.log('Name Valid');
      infoSpan.classList.add('checkmark');
      infoSpan.innerHTML = '*checkmark*';
    } else if(fName.value === '') {
      console.log('input is empty');
    } else {
      console.log('Name Invalid');
      fName.classList.add('errorBorder');
      infoSpan.classList.add('error');
      infoSpan.innerHTML = '*invalid input';
    }
  },
  validateEmail: function() {
    var fEmail = document.getElementById('fEmail');
    var emailContainer = document.querySelector('#emailContainer');
    var infoSpan = document.createElement('span');

    emailContainer.appendChild(infoSpan);
    fEmail.classList.remove('errorBorder');

    if (fEmail.value.match(regEmail)) {
      console.log('Email Valid');
      infoSpan.classList.add('checkmark');
      infoSpan.textContent = '*checkmark*';
    } else {
      console.log('Email Invalid');
      fEmail.classList.add('errorBorder');
      infoSpan.classList.add('error');
      infoSpan.textContent = '*invalid input';

    }
  },
  validateUserName: function() {
    var fUserName = document.getElementById('fUserName');
    var userNameContainer = document.querySelector('#userNameContainer');
    var infoSpan = document.createElement('span');

    userNameContainer.appendChild(infoSpan);
    fUserName.classList.remove('errorBorder');

    if (fUserName.value.match(regUserName)) {
      console.log('User Name Valid');
      infoSpan.classList.add('checkmark');
      infoSpan.textContent = '*checkmark*';
    } else {
      console.log('User Name Invalid');
      fUserName.classList.add('errorBorder');
      infoSpan.classList.add('error');
      infoSpan.textContent = '*invalid input';
    }
  },
  validatePassword: function() {
    var fPassword = document.getElementById('fPassword');
    var passwordContainer = document.querySelector('#passwordContainer');
    var infoSpan = document.createElement('span');

    passwordContainer.appendChild(infoSpan);
    fPassword.classList.remove('errorBorder');

    if (fPassword.value.match(regPassword)) {
      console.log('Passowrd Valid');
      infoSpan.classList.add('checkmark');
      infoSpan.textContent = '*checkmark*';
    } else {
      console.log('Passowrd Invalid');
      fPassword.classList.add('errorBorder');
      infoSpan.classList.add('error');
      infoSpan.textContent = '*invalid input';
    }
  }
};

function onSubmit() {
  validate.validateName();
  validate.validateEmail();
  validate.validateUserName();
  validate.validatePassword();
}

全名:
电邮:
用户名:
密码:

如果你看一下我的代码,你会看到有4个字段和一个提交按钮。现在JavaScript代码只是在输入字段旁边的标记中返回“checkmark”或“invalid input”,这取决于输入字段是否填充

我遇到的问题是,如果您多次点击提交按钮(再次运行所有函数),则
我只想显示最新的span标记集。或者换句话说,在插入span标记之前,检查它们是否存在于DOM中,如果存在则删除它们。

我更新了plaker并添加了一个函数,在提交之前清除所有错误。您的代码中缺少以下内容:

函数cleanErrors(){
var allErrors=document.querySelectorAll('forminput+span');
对于(变量i=0;i
使用您现有的HTML结构,要知道当前正在验证的
输入
元素之后是否有
span
元素,最简单的方法就是检查
input
元素的
nextementsibling
,看看它是否是
span
。如果是,则需要删除
nextElementSibling
,如果不是,则可以添加它

例如,在第一次验证中:

var fName = document.getElementById('fName');
// .getElementById() is faster than .querySelector() when looking for id's
var nameContainer = document.getElementById('nameContainer');

// Is the next element sibling of the field a span?
if(nameContainer.nextElementSibling.nodeName === "SPAN"){
  // span already exists - remove it
  nameContainer.parentNode.removeChild(nameContainer.nextElementSibling);
} else {
  // span does not exist - create and add it
  var infoSpan = document.createElement('span');
  nameContainer.appendChild(infoSpan);
}
尽管如此,这是完全不必要的,并且会影响性能,因为您正在反复修改DOM

由于您需要一个
span
,因此,只需在HTML中静态创建它们,然后只需更新它们的
textContent
(除非要解析HTML,否则不要使用
.innerHTML

var regName=/^[A-Za-z]+$/;
var regEmail=/^[A-Za-z]+$/;
var regUserName=/^[A-Za-z]+$/;
var regPassword=/^[A-Za-z]+$/;
var验证={
validateName:函数(){
var fName=document.getElementById('fName');
var nameContainer=document.querySelector(“#nameContainer”);
var infoSpan=document.getElementById('nameInfo');
fName.classList.remove('errorBorder');
if(fName.value.match(regName)){
console.log('Name Valid');
infoSpan.classList.add('checkmark');
infoSpan.textContent='*复选标记*';
}else if(fName.value==''){
log('输入为空');
}否则{
console.log('Name Invalid');
fName.classList.add('errorBorder');
infoSpan.classList.add('error');
infoSpan.textContent='*输入无效';
}
},
validateEmail:function(){
var fEmail=document.getElementById('fEmail');
var emailContainer=document.querySelector(“#emailContainer”);
var infoSpan=document.getElementById('emailInfo');
fEmail.classList.remove('errorBorder');
if(fEmail.value.match(regEmail)){
console.log('Email Valid');
infoSpan.classList.add('checkmark');
infoSpan.textContent='*复选标记*';
}否则{
console.log(“电子邮件无效”);
fEmail.classList.add('errorBorder');
infoSpan.classList.add('error');
infoSpan.textContent='*输入无效';
}
},
validateUserName:函数(){
var fUserName=document.getElementById('fUserName');
var userNameContainer=document.querySelector(“#userNameContainer”);
var infoSpan=document.getElementById('userNameInfo');
fUserName.classList.remove('errorBorder');
if(fUserName.value.match(regUserName)){
log('User Name Valid');
infoSpan.classList.add('checkmark');
infoSpan.textContent='*复选标记*';
}否则{
console.log('用户名无效');
fUserName.classList.add('errorBorder');
infoSpan.classList.add('error');
infoSpan.textContent='*输入无效';
}
},
validatePassword:function(){
var fPassword=document.getElementById('fPassword');
var passwordContainer=document.querySelector(“#passwordContainer”);
var infoSpan=document.getElementById('passwordInfo');
fPassword.classList.remove('errorBorder');
if(fPassword.value.match(regPassword)){
log('Passowrd Valid');
infoSpan.classList.add('checkmark');
infoSpan.textContent='*复选标记*';
}否则{
log('Passowrd Invalid');
fPassword.classList.add('errorBorder');
infoSpan.classList.add('error');
infoSpan.textContent='*输入无效';
}
}
};
函数onSubmit(){
validate.validateName();
validate.validateEmail();
validate.validateUserName();
validate.validatePassword();
}
/*样式在这里*/
标签,跨度{
字体系列:无衬线;
}
标签{
字体大小:14px;
}
表格组{
利润率:10px0;
}
标签{
显示:内联块;
宽度:85px;
}
.错误边界{
边框:细红色实心;
}
广度误差{
颜色:红色;
字体大小:12px;
显示:内联块;
左边距:10px;
}
span.复选标记{
颜色:绿色;
字体大小:粗体;
}

全名:
电邮:
用户名:
密码:


我要做的是为info div分配一个ID,这样您就可以首先尝试获取现有的infospan。然后检查它是否存在,如果我
var fName = document.getElementById('fName');
// .getElementById() is faster than .querySelector() when looking for id's
var nameContainer = document.getElementById('nameContainer');

// Is the next element sibling of the field a span?
if(nameContainer.nextElementSibling.nodeName === "SPAN"){
  // span already exists - remove it
  nameContainer.parentNode.removeChild(nameContainer.nextElementSibling);
} else {
  // span does not exist - create and add it
  var infoSpan = document.createElement('span');
  nameContainer.appendChild(infoSpan);
}