如何仅在输入有效时以 javascript 验证的形式显示 CSS 动画

How to show CSS animation in form with javascript validation only when input is valid

我制作了一个带有 js 验证的表单,如果输入无效,它会设置一个错误函数 (setErrorFor)。 如果输入有效(功能 showSucces),该表单有一个提交按钮,该按钮显示一个动画复选标记。当输入无效时,它不需要显示该复选标记。 所以我创建了一个函数(stopSendingData)来阻止成功函数的执行。但现在复选标记根本不显示,即使输入有效。

所以我尝试更改 stopSendingData 函数中的 if 语句,并通过更改停止它的方式进行了尝试,但没有任何尝试使复选标记仅在输入有效时显示。 我真的很期待听到我做错了什么以及如何解决这个问题。

// Listen for a submit
document.querySelector(".contactForm").addEventListener("submit", submitForm);

function submitForm(e) {
  e.preventDefault();

  checkInputs(); //val
  showSucces();
}

function showSucces() {
  document.getElementById("submitButton").classList.add("clicked");
  setTimeout(() => {
    document.getElementById("submitButton").classList.remove("clicked");
  }, 4000);
}

//form validaton
const namecontact = document.getElementById('namecontact'); //Val
const email = document.getElementById('email'); //Val
const message = document.getElementById('message'); //Val

function checkInputs() {
  //Get the values from the inputs
  const nameValue = namecontact.value.trim();
  const emailValue = email.value.trim();
  const messageValue = message.value.trim();
  const numbers = /^[0-9]+$/;

  if (nameValue === '') {
    setErrorFor(namecontact, "Name cannot be blank.");
  }

  if (nameValue.match(numbers)) {
    setErrorFor(namecontact, "Name can not contain number(s).");
  }

  if (emailValue === '') {
    setErrorFor(email, "Email cannot be blank.");
  } 
  else if (!isEmail(emailValue)) {
    setErrorFor(email, 'Email is not valid.');
  }

  if (messageValue === '') {
    setErrorFor(message, "Message cannot be blank.");
  }
  
  stopSendingData();
}

function setErrorFor(input, errorMessage) {
  const formControl = input.parentElement; //.form-control
  const small = formControl.querySelector('small');

  //add error message inside small
  small.innerText = errorMessage;

  // add error class
  formControl.className = 'form-control error';
}

function isEmail(email) {
  return /^(([^<>()\[\]\.,;:\s@"]+(\.[^<>()\[\]\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(email);
}

function stopSendingData() {
  // const small = document.querySelector('small');
  const small = getElementsByTagName('small');
  const formControl = small.parentElement; //.form-control
  
  if (formControl.className = 'form-control error') {
    return false;
  }
}
.contactForm {
  flex: 0%;
  margin: 0px 0px;
  width: 21%;
  position: absolute;
  margin: 90px 0px 0px 10.5px;
  left: 0px;
  /* max-width : 100%; */
  /* opacity   : 0.39; */
}

.name,
.email,
.subject {
  position: relative;
  width: 279px;
  height: 39px;
  padding: 9px 15px 15px 15px;
  margin-left: 39.9px;
  font-size: 13.2px;
}

.message {
  position: relative;
  width: 279px;
  height: 60px;
  padding: 9px 15px 15px 15px;
  margin-left: 39.9px;
  font-size: 13.2px;
}

::placeholder {
  margin-top: 0px;
  font-size: 12px;
}

.fas.fa-exclamation-circle {
  color: red;
  width: 15px;
  height: 15px;
  position: absolute;
  /* visibility : visible; */
  top: 15px;
  right: 60px;
}


/* 
.form-control input {
    border : 1px solid transparent;
  } */

.form-control {
  position: relative;
}

.form-control i.fas.fas.fa-exclamation-circle {
  visibility: hidden;
}

small {
  position: absolute;
  left: 75px;
  visibility: hidden;
  top: 24.9px;
  font-size: 13.5px;
  font-weight: bolder;
  z-index: 9;
  width: 300px;
}

.form-control.error input {
  border-color: red;
}

.form-control.error textarea {
  border-color: red;
}

.form-control.error i.fas.fas.fa-exclamation-circle {
  visibility: visible;
  color: red;
}

.form-control.error small {
  color: red;
  visibility: visible;
}

#submitButton {
  margin: 9px 0px 0px 42px;
  width: 277.2px;
  height: 27px;
}

#submitButton {
  position: relative;
  cursor: pointer;
  height: 30px;
  width: 90px;
  transition: all 1250ms cubic-bezier(0.19, 1, 0.22, 1);
}

#submitButton.clicked {
  background-color: rgb(4, 221, 250);
  color: rgb(21, 21, 24);
  font-weight: bold;
  font-size: 16.2px;
  opacity: 0.6;
  padding-top: 1.7px;
}

#submitButton.clicked span {
  animation: spanShrink 1.8s ease-in-out forwards;
}

@keyframes spanShrink {
  15% {
    opacity: 0;
  }
  85% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

#submitButton .checkmark {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  stroke-width: 3;
  stroke: rgb(18, 19, 19);
  stroke-miterlimit: 10;
  width: 51px;
  height: 51px;
  transform-origin: 50% 50%;
  stroke-dasharray: 48;
  stroke-dashoffset: 48;
}

#submitButton.clicked .checkmark {
  animation: stroke 1.5s ease-in-out 0.6s forwards;
}

@keyframes stroke {
  20% {
    stroke-dashoffset: 0;
  }
  50% {
    stroke-dashoffset: 0;
  }
  70% {
    stroke-dashoffset: 48;
  }
}
<form method="POST" class="contactForm" id="form">
  <div class="form-control">
    <input class="name" id="namecontact" type="text" placeholder="Name" /><br>
    <i class="fas fa-exclamation-circle" id="exclamation1"></i>
    <small></small>
  </div>
  <div class="form-control">
    <input class="email" id="email" placeholder="E-mail" /><br>
    <i class="fas fa-exclamation-circle" id="exclamation2"></i>
    <small></small>
  </div>
  <div class="form-control">
    <input class="subject" type="text" placeholder="Subject" /><br>
  </div>
  <div class="form-control">
    <textarea class="message" id="message" cols="30" rows="10" placeholder="Message"></textarea><br>
    <i class="fas fa-exclamation-circle" id="exclamation4"></i>
    <small></small>
  </div>
  <button id="submitButton" type="submit">
    <span>Launch</span>
    <svg class="checkmark" viewBox="0 0 52 52">
      <path fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8"/>
    </svg>
  </button>
  
  </div>
  
</form>

你这个问题的答案很简单, 只需创建一个 class 说 animating 并编写代码:

.animating{
    animation: animation-name 1s 1;
}

然后转到 javascript 文件并根据需要添加行并进行一些更改:

//let the element to be animated have id = 'input1'
document.getElementById('input1').classList.add('animating');//to add animation
//or
document.getElementById('input1').classList.remove('animating');//to remove animation

好吧,除了你明显对缩进感到恼火并且它让你阅读代码很痛苦之外,你的代码的第一个问题是你没有在你的表单中使用任何名称属性,而那些 -这些是必不可少的,因为它们是发送到服务器的数据的参考

它们在 JS 中也非常有用,因为它们在表单中也可以作为直接引用

<form name="my-form-name" id="my-form-id"  .... 

  <input name="namecontact" type="text" placeholder="Name" />

javascript 使用:

const myForm = document.forms['my-form-name']  
// or myForm = document.querySelector("#my-form-id")
  
  
// usage
 
function checkInputs()
  {
  const nameValue = myForm.namecontact.value.trim()
//                    |       | 
//                    |     name attribute 
//                    |
//                  form element
// ...

myForm.onsubmit = e =>
  {
  e.preventDefault()
  checkInputs() 
  showSucces() 
  }

要解决您的问题,您只需将 showSucces() 的调用移动到 stopSendingData() 的末尾即可。否则每次提交表单时都会调用它,即使检查失败也是如此。


顺便说一句:您的代码中存在一些问题:

  • 你必须在 getElementsByTagName() 之前调用 document.:
const small = document.getElementsByTagName('small');
  • getElementsByTagName() 生成元素的集合,而不是单个元素,因此您无法通过这种方式获取父元素。因此你必须遍历集合:
for (i = 0; i < small.length; i++) {
  if (small[i].parentElement.classList.contains('error')) {
    return false;
  }
}
  • 你有一个结束 div 到很多(在表格的末尾)

工作示例:

// Listen for a submit
document.querySelector(".contactForm").addEventListener("submit", submitForm);

function submitForm(e) {
  e.preventDefault();

  checkInputs(); //val
}

function showSucces() {
  document.getElementById("submitButton").classList.add("clicked");
  setTimeout(() => {
    document.getElementById("submitButton").classList.remove("clicked");
  }, 4000);
}

//form validaton
const namecontact = document.getElementById('namecontact'); //Val
const email = document.getElementById('email'); //Val
const message = document.getElementById('message'); //Val

function checkInputs() {
  //Get the values from the inputs
  const nameValue = namecontact.value.trim();
  const emailValue = email.value.trim();
  const messageValue = message.value.trim();
  const numbers = /^[0-9]+$/;

  if (nameValue === '') {
    setErrorFor(namecontact, "Name cannot be blank.");
  }

  if (nameValue.match(numbers)) {
    setErrorFor(namecontact, "Name can not contain number(s).");
  }

  if (emailValue === '') {
    setErrorFor(email, "Email cannot be blank.");
  } else if (!isEmail(emailValue)) {
    setErrorFor(email, 'Email is not valid.');
  }

  if (messageValue === '') {
    setErrorFor(message, "Message cannot be blank.");
  }

  stopSendingData();
}

function setErrorFor(input, errorMessage) {
  const formControl = input.parentElement; //.form-control
  const small = formControl.querySelector('small');

  //add error message inside small
  small.innerText = errorMessage;

  // add error class
  formControl.className = 'form-control error';
}

function isEmail(email) {
  return /^(([^<>()\[\]\.,;:\s@"]+(\.[^<>()\[\]\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(email);
}

function stopSendingData() {
  const small = document.getElementsByTagName('small');

  for (i = 0; i < small.length; i++) {
    if (small[i].parentElement.classList.contains('error')) {
      return false;
    }
  }

  showSucces();
}
.contactForm {
  flex: 0%;
  margin: 0px 0px;
  width: 21%;
  position: absolute;
  margin: 90px 0px 0px 10.5px;
  left: 0px;
  /* max-width : 100%; */
  /* opacity   : 0.39; */
}

.name,
.email,
.subject {
  position: relative;
  width: 279px;
  height: 39px;
  padding: 9px 15px 15px 15px;
  margin-left: 39.9px;
  font-size: 13.2px;
}

.message {
  position: relative;
  width: 279px;
  height: 60px;
  padding: 9px 15px 15px 15px;
  margin-left: 39.9px;
  font-size: 13.2px;
}

::placeholder {
  margin-top: 0px;
  font-size: 12px;
}

.fas.fa-exclamation-circle {
  color: red;
  width: 15px;
  height: 15px;
  position: absolute;
  /* visibility : visible; */
  top: 15px;
  right: 60px;
}


/* 
.form-control input {
    border : 1px solid transparent;
  } */

.form-control {
  position: relative;
}

.form-control i.fas.fas.fa-exclamation-circle {
  visibility: hidden;
}

small {
  position: absolute;
  left: 75px;
  visibility: hidden;
  top: 24.9px;
  font-size: 13.5px;
  font-weight: bolder;
  z-index: 9;
  width: 300px;
}

.form-control.error input {
  border-color: red;
}

.form-control.error textarea {
  border-color: red;
}

.form-control.error i.fas.fas.fa-exclamation-circle {
  visibility: visible;
  color: red;
}

.form-control.error small {
  color: red;
  visibility: visible;
}

#submitButton {
  margin: 9px 0px 0px 42px;
  width: 277.2px;
  height: 27px;
}

#submitButton {
  position: relative;
  cursor: pointer;
  height: 30px;
  width: 90px;
  transition: all 1250ms cubic-bezier(0.19, 1, 0.22, 1);
}

#submitButton.clicked {
  background-color: rgb(4, 221, 250);
  color: rgb(21, 21, 24);
  font-weight: bold;
  font-size: 16.2px;
  opacity: 0.6;
  padding-top: 1.7px;
}

#submitButton.clicked span {
  animation: spanShrink 1.8s ease-in-out forwards;
}

@keyframes spanShrink {
  15% {
    opacity: 0;
  }
  85% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

#submitButton .checkmark {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  stroke-width: 3;
  stroke: rgb(18, 19, 19);
  stroke-miterlimit: 10;
  width: 51px;
  height: 51px;
  transform-origin: 50% 50%;
  stroke-dasharray: 48;
  stroke-dashoffset: 48;
}

#submitButton.clicked .checkmark {
  animation: stroke 1.5s ease-in-out 0.6s forwards;
}

@keyframes stroke {
  20% {
    stroke-dashoffset: 0;
  }
  50% {
    stroke-dashoffset: 0;
  }
  70% {
    stroke-dashoffset: 48;
  }
}
<form method="POST" class="contactForm" id="form">
  <div class="form-control">
    <input class="name" id="namecontact" type="text" placeholder="Name" /><br>
    <i class="fas fa-exclamation-circle" id="exclamation1"></i>
    <small></small>
  </div>
  <div class="form-control">
    <input class="email" id="email" placeholder="E-mail" /><br>
    <i class="fas fa-exclamation-circle" id="exclamation2"></i>
    <small></small>
  </div>
  <div class="form-control">
    <input class="subject" type="text" placeholder="Subject" /><br>
  </div>
  <div class="form-control">
    <textarea class="message" id="message" cols="30" rows="10" placeholder="Message"></textarea><br>
    <i class="fas fa-exclamation-circle" id="exclamation4"></i>
    <small></small>
  </div>
  <button id="submitButton" type="submit">
    <span>Launch</span>
    <svg class="checkmark" viewBox="0 0 52 52">
      <path fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8"/>
    </svg>
  </button>
</form>