我的javascript出现问题。这看起来很奇怪。这是正在发生的事情。我有一个表单,在用户提交之后,它调用一个函数(onsubmit事件)来验证提交的数据,如果有什么不好或者如果用户名/电子邮件已经在数据库中(使用此部分的ajax)它将返回false并使用DOM显示错误。这是下面的代码。有什么奇怪的,它只有在我使用空警报('')消息时才有效,没有它,它就行不通。谢谢你的帮助。
//////////////////////////////////////
function httpRequest() {
var xmlhttp;
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
} else if (window.ActiveXObject) {
// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
} else {
alert("Your browser does not support XMLHTTP!");
}
return xmlhttp;
}
function validateRegForm(reg) {
var isValidForm = true;
var warningIcon = "";//for later in case we want to use an icon next to warning msg
with(reg) {
var regFormDiv = document.getElementById("registration_form");
//Check if dynamic div exist, if so, remove it
if(document.getElementById('disp_errors') != null) {
var dispErrorsDiv = document.getElementById('disp_errors');
document.getElementById('reg_form').removeChild(dispErrorsDiv);
}
//Dynamically create new 'div'
var errorDiv = document.createElement('div');
errorDiv.setAttribute('id','disp_errors');
errorDiv.setAttribute('style','background-color:pink;border:1px solid red;color:red;padding:10px;');
document.getElementById('reg_form').insertBefore(errorDiv,regFormDiv);
var xmlhttp = httpRequest();
var available = new Array();
xmlhttp.onreadystatechange = function() {
if(xmlhttp.readyState == 4)
{
var response = xmlhttp.responseText;
if(response != "") {
//Return values
var newValue = response.split("|");
available[0] = newValue[0];
available[1] = newValue[1];
}
}
}
xmlhttp.open("GET","profile_fetch_reg_info.php?do=available&un="+u_username.value+"&email="+u_email.value+"",true);
xmlhttp.send(null);
alert(' '); ////////////WITHOUT THIS, IT DOESN'T WORK. Why?
if(available[1] == "taken") {
errorDiv.innerHTML += warningIcon+'Username is already taken!<br />';
isValidForm = false;
} else if(u_username.value.length < 4){
errorDiv.innerHTML += warningIcon+'Username must be more than 4 characters long!<br />';
isValidForm = false;
} else if(u_username.value.length > 35) {
errorDiv.innerHTML += warningIcon+'Username must be less than 34 characters long!<br />';
isValidForm = false;
}
if(available[0] == "taken") {
errorDiv.innerHTML += warningIcon+'Email address entered is already in use!<br />';
isValidForm = false;
} else if(u_email.value == ""){
errorDiv.innerHTML += warningIcon+'Email address is required!<br />';
isValidForm = false;
} else {
//Determine if email entered is valid
var filter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
if (!filter.test(u_email.value)) {
errorDiv.innerHTML += warningIcon+'Email entered is invalid!<br />';
u_email.value = "";
isValidForm = false;
}
}
if(u_fname.value == ""){
errorDiv.innerHTML = warningIcon+'Your first name is required!<br />';
isValidForm = false;
}
if(u_lname.value == ""){
errorDiv.innerHTML += warningIcon+'Your last name is required!<br />';
isValidForm = false;
}
if(u_password.value.length < 4){
errorDiv.innerHTML += warningIcon+'Password must be more than 4 characters long!<br />';
isValidForm = false;
} else if(u_password.value.length > 35) {
errorDiv.innerHTML += warningIcon+'Password must be less than 34 characters long!<br />';
isValidForm = false;
} else if (u_password.value != u_password2.value) {
errorDiv.innerHTML += warningIcon+'Password and re-typed password don\'t match!<br />';
isValidForm = false;
}
if(u_squestion.value == ""){
errorDiv.innerHTML += warningIcon+'A security question is required!<br />';
isValidForm = false;
}
if(u_sanswer.value == ""){
errorDiv.innerHTML += warningIcon+'A security answer is required!<br />';
isValidForm = false;
}
if(u_address.value == ""){
errorDiv.innerHTML += warningIcon+'Address is required!<br />';
isValidForm = false;
}
if(u_city.value == ""){
errorDiv.innerHTML += warningIcon+'City is required!<br />';
isValidForm = false;
}
if(u_state.value == ""){
errorDiv.innerHTML += warningIcon+'State is required!<br />';
isValidForm = false;
}
if(u_zip.value == ""){
errorDiv.innerHTML += warningIcon+'Zip code is required!<br />';
isValidForm = false;
}
if(u_phone.value == ""){
errorDiv.innerHTML += warningIcon+'Phone number is required!<br />';
isValidForm = false;
}
if(isValidForm == false)
window.scroll(0,0);
return isValidForm;
}
}
答案 0 :(得分:11)
alert()
会有所帮助,因为这会延迟处理该函数中剩余的javascript(从alert()
到底部的所有内容),留出足够的时间来完成AJAX请求。 AJAX中的第一个字母代表“异步”,这意味着(默认情况下)响应将在“未来的某个时刻”进行,但不是立即进行。
一个修复(您应该不实现)是使处理同步(通过将open()
的第三个参数更改为false
),这将停止进一步处理您的脚本(以及整个网页)直到请求返回。这很糟糕,因为它会有效地冻结Web浏览器,直到请求完成。
正确的解决方法是重构代码,以便任何依赖于AJAX请求结果的处理都进入onreadystatechange
函数,并且不能在启动AJAX请求的main函数中。
通常处理的方法是修改你的DOM(在发送AJAX请求之前)使表单只读并显示某种“处理”消息,然后在AJAX响应处理程序中,如果一切正常(服务器正确响应和验证成功)在表单上调用submit()
,否则使表单再次变为可用并显示任何验证错误。
答案 1 :(得分:3)
问题是XMLHTTPRequest是异步的 - 它在后台发送请求,而不是等待它完成。
alert
语句导致代码等待,直到用户单击“确定”,在此期间请求完成。
您需要使用onreadystatechange
事件,如下所示:
xmlhttp.onreadystatechange = function() {
if(xmlhttp.readyState==4) {
// Do things
}
};
收到响应后,将调用您为此属性指定的方法。 (在其他时候,这就是为什么你需要检查readyState
是4)
答案 2 :(得分:2)
您正在发送请求异步,因为:
xmlhttp.open(..., true);
将true
作为第三个参数传递给open()
意味着代码将在结果返回之前继续运行。
alert()
在后续代码运行之前完成异步请求时间。
我通常建议将依赖于AJAX调用结果的所有代码移动到回调中:
if(xmlhttp.readyState == 4)
阻止,但在您的情况下,您需要调用的结果才能知道从验证函数返回什么。在这种情况下,您必须将false
传递给open()
,才能使用同步通话。然后你的后续代码将不会运行,直到响应回来。
答案 3 :(得分:0)
这是因为您的AJAX调用是异步的。 xmlhttp.send()
之后的代码立即执行。它不会等待你的ajax调用结束(除非你发出警报)。
将ajax调用后要执行的所有代码移动到回调方法,以确保在调用完成后运行它。
[编辑]:除了问题之外,我认为使用AJAX来验证表单然后允许用户提交通常的方式对我来说似乎有些奇怪。
您可以将验证分为两部分吗?一个可以完全在客户端完成,另一个涉及服务器端验证。您可以在提交时完全在服务器端执行第二部分,并将错误返回给客户端。
另一个选择是完全避免传统的提交。既然你正在进行ajax调用,为什么不在ajax调用本身中进行保存/编辑/删除需要提交?但请记住,如果用户禁用了javascript,您仍需要支持常规提交。
答案 4 :(得分:0)
这些人是对的,但我也肯定会从验证方法中返回bool,因此如果表单无效,表单的提交将被取消。
有些事情:
<form onsubmit="return IsValid();">
...
</form>
您也可以始终从 validateRegForm 返回false,并让 xmlhttp.onreadystatechange = function()提交表单(如果有效),或以其他方式显示您的错误消息。
答案 5 :(得分:0)
你必须将第三个参数传递给xmlhttp.open()为false,然后才能正常工作
答案 6 :(得分:0)
当我使用type =&#34; submit&#34;时遇到同样的问题,例如:
<button type="submit" class="btn btn-default" name="btn-login" id="btn-login" onclick="submitForm()">
<span class="glyphicon glyphicon-log-in"></span> Sign In
但我将其更改为键入=&#34;按钮&#34;它有效。
答案 7 :(得分:0)
<button onclick="AddComment();">Comment</button>
这是我的 ajax 代码开始的地方,AddComment() 函数点击了一个隐藏的 Asp:Button,它将通过更新面板向后端发送一个 ajax 调用...
为了解决这个问题,我所做的只是将 return false;
添加到我的按钮中。
<button onclick="AddComment(); return false;">Comment</button>
答案 8 :(得分:-1)
我遇到了同样的问题。删除alert("")
后,它无效。我想通了,这就是交易。
在HTML中,当您使用<button></button>
放置按钮时,浏览器的行为会有所不同;单击它时,在调用事件处理程序后,它会重新加载页面,这就是为什么你应该在代码之后放置alert("")
以防止页面重新加载。
您只需使用<input type="button" value="something">
代替<button></button>
即可阻止浏览器重新加载页面。
答案 9 :(得分:-2)
<?php
usleep(200000)// 2 seconds
之后的javascript(顺便说一句,需要将jQuery 1.9.1推迟到头部