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

The alert() helps because that delays the processing of the remaining javascript in that function (everything from the alert() down to the bottom), leaving enough time for the AJAX request to complete. The first letter in AJAX stands for "asynchronous" which means that (by default) the response will come in at "some point in the future" but not immediately.

One fix (which you should not implement) is to make the processing synchronous (by changing the third argument of open() to be false) which will stop further processing of your script (and the entire webpage) until the request returns. This is bad because it will effectively freeze the web browser until the request completes.

The proper fix is to restructure your code so that any processing that depends on the result of the AJAX request goes in to the onreadystatechange function, and can't be in the main function that initiates the AJAX request.

The way this is usually handled is to modify your DOM (before the AJAX request is sent) to make the form readonly and display some sort of "processing" message, then in the AJAX response handler, if everything is okay (the server responded properly and validation was successful) call submit() on the form, otherwise make the form wriable again and display any validation errors.

于 2009-08-12T17:17:10.597 に答える
3

問題は、XMLHTTPRequest が非同期であることです。リクエストをバックグラウンドで送信し、完了するまで待機しません。

このalertステートメントにより、ユーザーが [OK] をクリックするまでコードが待機し、その間に要求が終了します。

onreadystatechange次のように、イベントを使用する必要があります。

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

このプロパティに割り当てたメソッドは、応答の受信後に呼び出されます。(それ以外の場合は、それが 4 であることを確認する必要がありますreadyState)

于 2009-08-12T17:16:02.910 に答える
2

次の理由により、リクエストを非同期で送信しています。

xmlhttp.open(..., true);

trueの 3 番目の引数として渡すopen()ことは、結果が返される前にコードが実行され続けることを意味します。

alert()、後続のコードが実行される前に、その非同期要求が完了する時間を与えています。

通常、AJAX 呼び出しの結果に依存するすべてのコードをコールバックに移動することをお勧めします。

if(xmlhttp.readyState == 4)

ブロックしますが、あなたの場合、検証関数から何を返すかを知るために呼び出しの結果が必要です。その場合、 に渡すfalseことにより、同期呼び出しを使用する必要がありますopen()。その後、応答が返されるまで、後続のコードは実行されません。

于 2009-08-12T17:13:00.450 に答える
0

3 番目のパラメーターを xmlhttp.open() に false として渡す必要があります。その後、正常に動作します。

于 2009-08-12T17:31:45.247 に答える
0

これは、AJAX 呼び出しが非同期であるためです。次のコードxmlhttp.send()はすぐに実行されます。ajax 呼び出しが終了するのを待ちません (アラートを設定しない限り)。

ajax 呼び出しの後に実行されるすべてのコードをコールバック メソッドに移動して、呼び出しの終了後に確実に実行されるようにします。

[編集]:問題は別として、フォームを検証するためだけに AJAX を使用し、ユーザーが通常の方法で送信できるようにするのは、私には少し奇妙に思えます。

検証を 2 つの部分に分割できますか? 1 つは純粋にクライアント側で実行できるもので、もう 1 つはサーバー側の検証を伴うものです。送信時にサーバー側で 2 番目の部分を完全に実行し、エラーをクライアントに返すことができます。

もう 1 つのオプションは、従来の送信を完全に回避することです。とにかく 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
<button onclick="AddComment();">Comment</button>

これは、私の ajax コードが開始された場所です。AddComment() 関数は、updatepanel を介してバックエンドに ajax 呼び出しを送信する非表示の Asp:Button をクリックしました...

状況を修正するために私がしたこと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 に答える