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

时间:2017-12-13 19:48:13

标签: 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 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();
}
    <form onsubmit="return false">

      <div id="nameContainer">
        <label>Full Name: </label>
        <input type="text" id="fName" />
      </div>

      <div id="emailContainer">
        <label>Email: </label>
        <input type="text" id="fEmail" />
      </div>

      <div id="userNameContainer">
        <label>User Name: </label>
        <input type="text" id="fUserName" />
      </div>

      <div id="passwordContainer">
        <label>Password: </label>
        <input type="password" id="fPassword" />
      </div>

      <br />

      <input type="submit" value="submit" onclick="onSubmit()" />

    </form>

如果您查看我的代码,您会看到有4个字段和一个提交按钮。现在,JavaScript代码只返回&#34; checkmark&#34;或&#34;无效输入&#34;内部标签接下来输入字段取决于输入字段是否填充。

我遇到的问题是,如果您不止一次点击提交按钮(运行所有功能agani),

我想只显示最新的span标签集。或者换句话说,在插入span标签之前,检查它们是否存在于DOM中,如果存在则删除它们。

3 个答案:

答案 0 :(得分:0)

我更新了plaker并添加了一个在提交之前清除所有错误的函数。您的代码中遗漏了这些内容:https://plnkr.co/edit/tIvl5rplqAP53ylzLLtf?p=preview

function cleanErrors() {
  var allErrors = document.querySelectorAll('form input + span');
  for (var i=0; i < allErrors.length; i++) {
    console.log('error',allErrors[i]);
    allErrors[i].parentNode.removeChild(allErrors[i]);
  }
}
function onSubmit() {
  cleanErrors();
  validate.validateName();
  validate.validateEmail();
  validate.validateUserName();
  validate.validatePassword();
}

答案 1 :(得分:0)

我要做的是为信息div分配一个ID,这样你就可以先尝试获取现有的infospan。然后检查它是否存在,如果它只是使用它,如果它不创建它。

//var regName = /^[A-Za-z]+ [A-Za-z]+$/;
//var regEmail = /\w{1-20}@\w{1-10}.\w{2-3}/;
//var regUserName = /^[A-Za-z0-9_-]{1,20}$/;
//var regPassword = /^[A-Za-z0-9!@#$%^&*()_-]{6,20}$/; 

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.getElementById('fNameInfo');
    
    if (!infoSpan) {
      infoSpan = document.createElement('span');
      infoSpan.id = 'fNameInfo';
      nameContainer.appendChild(infoSpan);
    }
  
    
    fName.classList.remove('errorBorder');
    infoSpan.classList.remove('checkmark');
    infoSpan.classList.remove('error');

    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.getElementById('fEmailInfo');
    
    if (!infoSpan) {
      infoSpan = document.createElement('span');
      infoSpan.id = 'fEmailInfo';
      emailContainer.appendChild(infoSpan);
    }
    
    fEmail.classList.remove('errorBorder');
    infoSpan.classList.remove('checkmark');
    infoSpan.classList.remove('error');
    
    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.getElementById('fUserNameInfo');
    
    if (!infoSpan) {
      infoSpan = document.createElement('span');
      infoSpan.id = 'fUserNameInfo';
      userNameContainer.appendChild(infoSpan);
    }
    
    fUserName.classList.remove('errorBorder');
    infoSpan.classList.remove('checkmark');
    infoSpan.classList.remove('error');

    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.getElementById('fPasswordInfo');
    
    if (!infoSpan) {
      infoSpan = document.createElement('span');
      infoSpan.id = 'fPasswordInfo';
      passwordContainer.appendChild(infoSpan);
    }
    
    fPassword.classList.remove('errorBorder');
    infoSpan.classList.remove('checkmark');
    infoSpan.classList.remove('error');

    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();
}
/* Styles go here */

label, span {
  font-family: sans-serif;
}

label {
  font-size: 14px;
}

form div {
  margin: 10px 0;
}

label {
  display: inline-block;
  width: 85px;
}

.errorBorder {
  border: thin red solid;
}

span.error {
  color: red;
  font-size: 12px;
  display: inline-block;
  margin-left: 10px;
}

span.checkmark {
  color: green;
  font-weight: bold;
}
<form onsubmit="return false">
      
      <div id="nameContainer">
        <label>Full Name: </label>
        <input type="text" id="fName" />
      </div>
      
      <div id="emailContainer">
        <label>Email: </label>
        <input type="text" id="fEmail" />
      </div>
      
      <div id="userNameContainer">
        <label>User Name: </label>
        <input type="text" id="fUserName" />
      </div>
      
      <div id="passwordContainer">
        <label>Password: </label>
        <input type="password" id="fPassword" />
      </div>
      
      <br />
      
      <input type="submit" value="submit" onclick="onSubmit()" />
      
    </form>

答案 2 :(得分:-2)

使用您拥有的HTML结构,了解正在验证的当前span元素之后是否存在input元素的最简单方法是检查nextElementSiblinginput元素中查看它是否为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 validate = {
  validateName: function() {
    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 = '*checkmark*';
    } else if(fName.value === '') {
      console.log('input is empty');
    } else {
      console.log('Name Invalid');
      fName.classList.add('errorBorder');
      infoSpan.classList.add('error');
      infoSpan.textContent = '*invalid input';
    }
  },
  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 = '*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.getElementById('userNameInfo');
    
    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.getElementById('passwordInfo');
    
    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();
}
/* Styles go here */

label, span {
  font-family: sans-serif;
}

label {
  font-size: 14px;
}

form div {
  margin: 10px 0;
}

label {
  display: inline-block;
  width: 85px;
}

.errorBorder {
  border: thin red solid;
}

span.error {
  color: red;
  font-size: 12px;
  display: inline-block;
  margin-left: 10px;
}

span.checkmark {
  color: green;
  font-weight: bold;
}
<form onsubmit="return false">
      
      <div id="nameContainer">
        <label>Full Name: </label>
        <input type="text" id="fName"><span id="nameInfo"></span>
      </div>
      
      <div id="emailContainer">
        <label>Email: </label>
        <input type="text" id="fEmail"><span id="emailInfo"></span>
      </div>
      
      <div id="userNameContainer">
        <label>User Name: </label>
        <input type="text" id="fUserName"><span id="userNameInfo"></span>
      </div>
      
      <div id="passwordContainer">
        <label>Password: </label>
        <input type="password" id="fPassword"><span id="passwordInfo"></span>
      </div>
      
      <br />
      
      <input type="submit" value="submit" onclick="onSubmit()">
      
    </form>

您可能还想重新考虑整个设计,因为除了用于确定有效性的正则表达式之外,每个验证函数基本相同。此外,您还可以使用具有内置验证的HTML5表单字段或完整的API供您使用。

// Do all event wiring in JavaScript, not with HTML event attributes
// And, form validation should be done on the form's submit event and
// the form submission should be cancelled via the event object that
// is automatically passed to the function
document.querySelector("form").addEventListener("submit", function(evt){

  // Store regular expressions in an object
  var regs = {
    regName : /^[A-Za-z]+$/,
    regEmail : /^[A-Za-z]+$/,
    regUserName : /^[A-Za-z]+$/,
    regPassword : /^[A-Za-z]+$/
  };
    
  var valid = true;  // Set up variable to track any errors

  // Gather up all the fields to be validated into an array.
  var fieldsToValidate = Array.prototype.slice.call(document.querySelectorAll(".validate"));
  
  // Loop over each of the fields to be validated
  fieldsToValidate.forEach(function(field, index){
    var message = "";
    var infoSpan = field.nextElementSibling;
    
    // Test the field against the corresponding regular expression in the object
    if(field.value.match(regs[Object.keys(regs)[index]])){
      message = "*checkmark*";
      infoSpan.classList.remove("error");      
      infoSpan.classList.add("checkmark");
    } else {
      valid = false;
      message = "*error*";
      infoSpan.classList.remove("checkmark");    
      infoSpan.classList.add("error");       
    }

    infoSpan.textContent = message; 
  });
    
  // If there were any errors, prevent the form from being submitted
  if(!valid){ evt.preventDefault(); }
});
label, span { font-family: sans-serif; }
label { font-size: 14px; display: inline-block; width: 85px; }
form div { margin: 10px 0; }
.error {
  color: red;
  font-size: 12px;
  display: inline-block;
  margin-left: 10px;
  border: thin red solid; 
}
.checkmark {
  color: green;
  font-weight: bold;
}
<form>    
  <div>
    <label>Full Name: </label>
    <input type="text" id="fName" class="validate"><span id="nameInfo"></span>
  </div>
      
  <div>
    <label>Email: </label>
    <input type="text" id="fEmail" class="validate"><span id="emailInfo"></span>
  </div>
      
  <div>
    <label>User Name: </label>
    <input type="text" id="fUserName" class="validate"><span id="userNameInfo"></span>
  </div>
      
  <div>
    <label>Password: </label>
    <input type="password" id="fPassword" class="validate"><span id="passwordInfo"></span>
  </div>
      
  <div><input type="submit" value="submit"></div>
</form>