我制作了一个带有js验证的表单,如果输入无效,它会设置一个错误函数(setErrorFor(。表单有一个提交按钮,如果输入有效,该按钮将显示一个动画复选标记(函数showSucces(。当输入无效时,不需要显示该复选标记。所以我创建了一个函数(stopSendingData(来阻止successs函数的执行。但现在,即使输入有效,复选标记也根本不显示。
因此,我尝试更改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>
要解决问题,只需将showSucces()
的调用移动到stopSendingData()
的末尾即可。否则,即使检查失败,每次提交表单时都会调用它。
顺便说一句:您的代码中存在一些问题:
- 您必须先用
document.
调用getElementsByTagName()
:
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;
}
.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;
top: 15px;
right: 60px;
}
.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>
这个问题的答案很简单,只需创建一个类,比如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()
}