7

我的 javascript 有问题。它似乎表现得很奇怪。这就是正在发生的事情。我有一个表单,在用户提交后,它会调用一个函数(onsubmit 事件)来验证提交的数据,如果有问题或者用户名/电子邮件已经在数据库中(这部分使用 ajax)它会返回 false并使用 DOM 显示错误。这是下面的代码。奇怪的是,它仅在我使用空的 alert('') 消息时才有效,没有它,它就不起作用。谢谢您的帮助。

//////////////////////////////////////

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;
    }

}
4

10 回答 10

11

alert()会有所帮助,因为这会延迟该函数中剩余 javascript 的处理(从alert()下到下的所有内容),从而为 AJAX 请求的完成留出足够的时间。AJAX 中的第一个字母代表“异步”,这意味着(默认情况下)响应将在“未来的某个时间点”出现,但不会立即出现。

一种解决方法(您不应该实现)是使处理同步(通过更改open()to的第三个参数false),这将停止进一步处理您的脚本(和整个网页),直到请求返回。这很糟糕,因为它会有效地冻结 Web 浏览器,直到请求完成。

正确的解决方法是重构您的代码,以便任何依赖于 AJAX 请求结果的处理都进入onreadystatechange函数,并且不能在启动 AJAX 请求的主函数中。

通常处理的方式是修改您的 DOM(在发送 AJAX 请求之前)以使表单只读并显示某种“处理”消息,然后在 AJAX 响应处理程序中,如果一切正常(服务器正确响应并且验证成功)调用submit()表单,否则使表单再次可写并显示任何验证错误。

于 2009-08-12T17:17:10.597 回答
3

问题是 XMLHTTPRequest 是异步的——它在后台发送请求并且不等待它完成。

alert语句使代码等待,直到用户单击确定,在此期间请求完成。

您需要使用该onreadystatechange事件,如下所示:

xmlhttp.onreadystatechange = function() {
    if(xmlhttp.readyState==4) {
        // Do things
    }
};

您分配给此属性的方法将在收到响应后调用。(在其他时候,这就是为什么你需要检查readyState是 4)

于 2009-08-12T17:16:02.910 回答
2

您正在异步发送请求,因为:

xmlhttp.open(..., true);

true作为第三个参数传递给open()意味着代码将在结果返回之前继续运行。

alert()是在后续代码运行之前给异步请求时间来完成。

我通常建议将所有依赖于 AJAX 调用结果的代码移到回调中,在:

if(xmlhttp.readyState == 4)

块,但在您的情况下,您需要调用结果才能知道从验证函数返回什么。在这种情况下,您将不得不使用同步调用,通过传递falseopen(). 然后,在响应返回之前,您的后续代码将不会运行。

于 2009-08-12T17:13:00.450 回答
0

那是因为您的 AJAX 调用是异步的。下面的代码xmlhttp.send()立即执行。它不会等待您的 ajax 调用结束(除非您发出警报)。

将ajax调用后要执行的所有代码移到回调方法中,确保调用完成后运行。

[编辑]:除了这个问题,我认为使用 AJAX 只是为了验证表单然后允许用户以通常的方式提交对我来说似乎有点奇怪。

您可以将验证分为两部分吗?一个可以纯粹在客户端完成,另一个涉及服务器端验证。您可以在提交后完全在服务器端完成第二部分并将错误返回给客户端。

另一种选择是完全避免传统的提交。既然您无论如何都在进行 ajax 调用,为什么不在 ajax 调用本身中进行保存/编辑/任何操作,从而无需提交?但请记住,如果用户禁用了 javascript,您仍然需要支持常规提交。

于 2009-08-12T17:13:52.727 回答
0

这些人是对的,但我也一定会从验证方法返回布尔值,因此如果表单无效,则取消表单的提交。

类似于以下内容:

<form onsubmit="return IsValid();">

...

</form>

您也可以始终从validateRegForm返回 false并让xmlhttp.onreadystatechange = function()提交有效的表单,或者显示您的错误消息。

于 2009-08-12T17:14:27.170 回答
0

您必须将第三个参数传递给 xmlhttp.open() 为 false,然后它将正常工作

于 2009-08-12T17:31:45.247 回答
0

我在使用 type="submit" 时遇到了同样的问题,例如:

<button type="submit" class="btn btn-default" name="btn-login" id="btn-login" onclick="submitForm()">
  <span class="glyphicon glyphicon-log-in"></span> &nbsp; Sign In

但我将其更改为 type="button" 并且它可以工作。

于 2017-06-13T12:39:18.840 回答
0
<button onclick="AddComment();">Comment</button>

这是我的 ajax 代码开始的地方,AddComment() 函数单击了一个隐藏的 Asp:Button,它将通过更新面板向后端发送 ajax 调用...

我为解决这种情况所做的只是添加return false;到我的按钮中。

<button onclick="AddComment(); return false;">Comment</button>
于 2021-03-22T16:37:29.630 回答
-1

我有同样的问题。一旦我删除alert("")它就不起作用了。我想通了,这就是交易。

在 HTML 中,当您<button></button>用来放置按钮时,浏览器的行为会有所不同;当您单击它时,在调用事件处理程序后,它会重新加载页面,这就是为什么您应该alert("")在代码之后放置一个以防止页面重新加载的原因。

您可以简单地使用<input type="button" value="something">而不是<button></button>防止浏览器重新加载页面。

于 2012-07-03T08:11:35.753 回答
-2

我遇到了同样的问题,只是添加了:

    <?php
    usleep(200000)// 2 seconds

?>

在javascript之后(顺便说一句,需要将jQuery 1.9.1推迟到头部

于 2013-05-04T00:58:52.267 回答