【发布时间】:2016-05-14 13:58:01
【问题描述】:
我正在尝试编写一个代码,如果用户名/邮件已经注册,它将检查一个 php 文件。以下代码不起作用,因为在 check_fields() 中,当为两个文件触发 check_field() 时,会立即发送返回,而无需等待异步查询完成。我不想使用 JQuery,所以我考虑执行以下操作:
- 一个函数链接到表单的onsubmit
- 对服务器进行 AJAX 调用以启动 php 文件
- 此文件分析输入并在需要时返回错误响应:“字段为空”、“电子邮件已使用”、“电子邮件地址不正确”等...
- 当 AJAX 调用完成时,将触发一个函数(或回调)。此函数将检查
<span id="username_err"></>和<span id="mail_err"></>的.textContent 以查看php 是否注意到错误。如果它不为空(输入有问题),则函数返回 false 到初始函数。 - 返回值被发送回表单
- 如果为真,则将表单提交到服务器...
这就是我想尝试的,可以吗?有没有办法在没有承诺的情况下做到这一点?
[原码]
<html>
<body>
<form style="text-align:center" action="mama.php" method="post" onsubmit="return check()">
<div class="username">
<span id="label_username">Username :</span>
<input type="text" id="username" name="username">
<p id="username_err"></p>
</div><br />
<div class="mail">
<span id="label_mail">Mail :</span>
<input type="text" id="mail" name="mail"></input>
<p id="mail_err"></p>
</div><br />
<input type="submit" id="envoyer" value="Envoyer" />
</form>
</body>
<script>
function check() {
return check_fields(['username', 'mail']);
}
function check_fields(items) {
var check = true;
for (i = 0; i < items.length; i++) {
check_field(items[i]);
};
for (i = 0; i < items.length; i++) {
var value = document.getElementById(items[i] + '_err').textContent;
if (value != '') {
check = false
}
};
return check
}
function check_field(id) {
var value = document.getElementById(id).value;
ajax_php(id, value, 'check_field.php', function(returned_value) {
document.getElementById(id + '_err').innerHTML = returned_value;
});
}
function ajax_php(id, value, file, fn) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
fn(xmlhttp.responseText);
}
};
xmlhttp.open('GET', file + '?' + id + '=' + value, true);
xmlhttp.send();
}
</script>
</html>
[可能的解决方案]
<html>
<body>
<form style="text-align:center" action="mama.php" method="post" onsubmit="check(this)">
<div class="username">
<span id="label_username">Username :</span>
<input type="text" id="username" name="username">
<p id="username_err"></p>
</div><br />
<div class="mail">
<span id="label_mail">Mail :</span>
<input type="text" id="mail" name="mail"></input>
<p id="mail_err"></p>
</div><br />
<input type="submit" id="envoyer" value="Envoyer" />
</form>
</body>
<script>
function check_fields(form, items) {
var success = true;
function check_field(i) {
var id = items[i];
var value = document.getElementById(id).value;
ajax_php(id, value, 'check_field.php', function(returned_value) {
document.getElmentById(id + '_err').textContent = returned_value;
if (returned_value != '') {
success = false;
}
if (++i < items.length) {
check_field(i); // Check the next field
} else if (success) { // reached the last field with no errors
form.submit();
}
});
}
check_field(0);
}
function check(form) {
check_fields(form, ['username', 'mail']);
return false; // prevent form submission
}
function ajax_php(id, value, file, fn) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
fn(xmlhttp.responseText);
};
};
xmlhttp.open('GET', file + '?' + id + '=' + value, true);
xmlhttp.send();
};
</script>
</html>
【问题讨论】:
-
不要使用
.innerText,使用.textContent。innerText不是标准的,在 FireFox 中不存在。 -
谢谢@Barmar 我会修改它。还有其他帮助吗?
-
由于 AJAX 是异步的,因此您无法在循环之后立即检查
textContent。您必须在回调函数中执行此操作。您应该做的是链接 AJAX 调用:检查第一个字段,然后在其回调函数中检查下一个字段,依此类推。如果您成功通过所有字段,则最后一个回调提交表单。 -
好的 @Barmar 我已经编辑了代码 sn-p。如果它们都是链接的,例如第一个字段有错误,它不会检查下一个字段,对吧?
-
这取决于你如何编码。当前一个显示错误时,没有什么可以阻止您进行下一个验证检查。您可以设置一个变量来保存其中是否有任何错误,最后在提交表单之前检查此变量。这将允许您标记所有错误的字段,而不仅仅是第一个。
标签: javascript ajax