我正在构建一个注册页面,我希望在所有输入都通过验证之前禁用该按钮。好吧,我已经完成了所有本机验证逻辑(缺少值,模式不匹配等等),但我想实现一个“用户名/可用”验证,其中按钮仍然无法启用,直到用户名拥有所有输入的有效输入并提供了尚未使用的所需用户名。
我有服务器调用,所有这一切都完成了,我唯一的问题是实际启用/禁用按钮并将边框类分配给输入。以下是我对AJAX调用响应的代码:
ajax.onload = function() {
if (this.responseText === "taken") {
if (username.classList.contains("taken")) {
return;
} else {
username.classList.remove("successBorder");
username.classList.add("errorBorder");
username.classList.add("taken");
}
} else {
if (!username.checkValidity()) {
username.classList.remove("successBorder");
username.classList.add("errorBorder");
return;
} else {
username.classList.remove("errorBorder");
username.classList.add("successBorder");
username.classList.remove("taken");
}
}
}
然后,这是在每个输入元素的输入事件上调用启用/禁用按钮的代码:
function validate() {
if (document.querySelector("form").checkValidity() && !(username.classList.contains("taken"))) {
registerButton.removeAttribute("disabled");
const ruleSpans = document.querySelectorAll("span[data-rule]");
for (span of ruleSpans) {
span.classList.add("hide");
}
for (input of inputs) {
input.classList.remove("errorBorder");
input.classList.add("successBorder");
}
return;
}
registerButton.setAttribute("disabled", "true");
if (this.checkValidity()) {
// Get rid of the error messages
this.classList.remove("errorBorder");
this.classList.add("successBorder");
const ruleSpans = document.getElementsByClassName(this.id);
for (span of ruleSpans) {
span.classList.add("hide");
}
return;
}
// Adding attention borders and error messages based upon what the issue is
this.classList.remove("successBorder");
this.classList.add("errorBorder");
const ruleSpans = document.getElementsByClassName(this.id);
for (span of ruleSpans) {
span.classList.add("hide");
switch (span.getAttribute("data-rule")) {
case "patternMismatch":
if (this.validity.patternMismatch) {
span.classList.remove("hide");
}
break;
case "valueMissing":
if (this.validity.valueMissing) {
span.classList.remove("hide");
}
break;
case "typeMismatch":
if (this.validity.typeMismatch) {
span.classList.remove("hide");
}
break;
}
}
}
现在,禁用/启用工作如果它是第一次输入该元素,但它在第一次之后的所有时间都“落后”。 (例如,如果使用了用户名,则启用注册按钮,但如果使用了用户名,则注册按钮被禁用,与我想要发生的完全相反)。
所以我想,不是以正确的方式检查它(我在代码!(username.classList.contains("taken"))
中的方式),我会将逻辑反转为:username.classList.contains("taken")
。这是有效的(即使它在逻辑上是错误的并且令人难以置信地被黑客攻击),除了第一次使用用户名之外。
我在这里做什么逻辑错误?
答案 0 :(得分:1)
我建议您使用像这样的代码结构
function serverValidation () { //make the ajax call here to validate all server validation //send the success callback handler to 'clientValidations' } function clientValidations(){ //validate other form elements that does not require a server request here //Then submit the form through an ajax form submit submitFormThroughAjax(); } function submitFormThroughAjax() { //submit the form through ajax. } function onSubmit(event) { event.preventDefault(); serverValidation(); } //Here onSubmit should be attached to the form submit handler.
请参阅以下链接,了解如何通过ajax提交表单。
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
此示例仅在用户提交后执行所有验证,但如果您希望在用户交互时立即显示错误,则需要通过特定的表单元素事件处理它。