سؤال

أواجه مشكلة مع جافا سكريبت. يبدو أن تتصرف بشكل غريب. هذا ما يحدث. لدي نموذج، بعد أن يقدم المستخدم، فهو يستدعي وظيفة (حدث 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;
    }

}
هل كانت مفيدة؟

المحلول

ال alert() يساعد لأن هذا يؤخر معالجة JavaScript المتبقية في هذه الوظيفة (كل شيء من alert() وصولا الى القاع)، تاركة وقتا كافيا لطلب أياكس لإكمال. تقف الحرف الأول في AJAX ل "غير متزامن" مما يعني أنه (افتراضي) سيأتي الاستجابة في "نقطة في المستقبل" ولكن ليس على الفور.

إصلاح واحد (الذي يجب عليك ليس تنفيذ) هو جعل المعالجة متزامنة (عن طريق تغيير الوسيطة الثالثة لل open() أن تكون false) والتي ستتوقف عن مزيد من معالجة البرنامج النصي الخاص بك (وأكملها صفحة الويب) حتى يعود الطلب. هذا سيء لأنه سيتم تجميد متصفح الويب بشكل فعال حتى يكمل الطلب.

الإصلاح المناسب هو إعادة هيكلة التعليمات البرمجية الخاصة بك بحيث يذهب أي معالجة يعتمد على نتيجة طلب AJAX إلى onreadystatechange وظيفة، ولا يمكن أن تكون في الوظيفة الرئيسية التي تبدأ طلب AJAX.

الطريقة التي يتم التعامل معها عادة ما يتم التعامل مع DOM (قبل إرسال طلب AJAX) لجعل النموذج Readonly وعرض نوعا من رسالة "المعالجة"، ثم في معالج استجابة Ajax، إذا كان كل شيء على ما يرام (استجاب الخادم بشكل صحيح و كان التحقق من الصحة ناجحا) submit() في النموذج، وإلا فإن النموذج غير قابل للحل مرة أخرى وعرض أي أخطاء صحيحة.

نصائح أخرى

المشكلة هي أن xmlhttprequest غير متزامن - إنه يرسل الطلب في الخلفية ولا ينتظر ذلك.

ال alert يسبب العبارة التعليمات البرمجية للانتظار حتى ينقر المستخدم موافق، والتي ينتهي خلالها الطلب.

تحتاج إلى استخدام onreadystatechange الحدث، مثل هذا:

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

سيتم استدعاء الطريقة التي تقوم بتعيينها بهذه الخاصية بعد استلام الاستجابة. (وفي أوقات أخرى، وهذا هو السبب في أنك تحتاج إلى التحقق من ذلك readyState هو 4)

أنت ترسل الطلب غير متزامن, ، و لهذا:

xmlhttp.open(..., true);

تمر true كما الحجة الثالثة ل open() يعني أن الرمز سوف يستمر في الركض قبل أن تعود النتيجة.

ال alert() هو إعطاء الوقت طلب غير متزامن لإكماله قبل تشغيل التعليمات البرمجية اللاحقة.

كنت أوصي عادة بتحريك جميع التعليمات البرمجية التي تعتمد على نتيجة استدعاء AJAX في رد الاتصال، داخل:

if(xmlhttp.readyState == 4)

كتلة، ولكن في حالتك تحتاج إلى نتيجة للمكالمات لمعرفة ما يجب إرجاعه من وظيفة التحقق من الصحة. في هذه الحالة، ستضطر إلى استخدام مكالمة متزامنة، عن طريق المرور false ل open(). وبعد ثم لن يتم تشغيل رمزك اللاحق حتى تعود الرد.

هؤلاء الرجال على حق ولكن سأكون متأكدين أيضا من إرجاع BOOL من طريقة التحقق من الصحة حتى يتم إلغاء تقديم النموذج إذا كان النموذج غير صالح.

شيء على غرار:

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

...

</form>

يمكنك أيضا العودة دائما خطأ ValidAteregForm. ويكون XMLHTTP.ONREADYSTATECHANGE = وظيفة () إرسال النموذج إذا كان صحيحا، أو عرض رسالة الخطأ الخاصة بك.

هذا لأن دعوة AJAX الخاصة بك غير متزامن. الكود التالي xmlhttp.send() يتم تنفيذها على الفور. لا تنتظر دعوة AJAX الخاصة بك إلى النهاية (إلا إذا وضعت التنبيه).

نقل جميع التعليمات البرمجية المراد تنفيذها بعد استدعاء AJAX إلى طريقة رد الاتصال للتأكد من تشغيلها بعد الانتهاء من المكالمة.

يحرر]: بصرف النظر عن المشكلة، أعتقد أن استخدام AJAX فقط للتحقق من صحة النموذج ثم السماح للمستخدم بإرسال الطريقة المعتادة تبدو غريبة بعض الشيء.

يمكنك تقسيم التحقق من الصحة إلى 2 أجزاء؟ واحد يمكن القيام به بحتة على الجانب العميل والآخر الذي ينطوي على التحقق من جانب الخادم. يمكنك القيام بالجزء الثاني تماما على جانب الخادم عند إرسال وإرجاع الأخطاء مرة أخرى إلى العميل.

خيار آخر هو تجنب تقديم التقليدية تماما. نظرا لأنك تقوم بإجراء مكالمة AJAX على أي حال، فلماذا لا تفعل حفظ / تحرير / أي شيء في AJAX استدعاء نفسه لإزالة الحاجة إلى إرسال؟ ضع في اعتبارك رغم ذلك، ستحتاج إلى دعم الإرسال العادي إذا كان المستخدم قد تم تعطيل JavaScript.

يجب عليك تمرير المعلمة الثالثة إلى xmlhttp.open () كخطأ، ثم سيعمل بشكل جيد

كنت أواجه نفس المشكلة عندما كنت أستخدم النوع = "إرسال"، على سبيل المثال:

<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

لكنني قمت بتغييره لكتابة = "زر" ويعمل.

لقد قضيت نفس المشكلة. بمجرد إزالة alert("") لا يعمل. احسبها وهذا هو الصفقة.

في أتش تي أم أل، عند استخدامك <button></button> لوضع الزر الخاص بك، يتصرف المتصفح بشكل مختلف؛ عند النقر فوقه، بعد استدعاء معالج الأحداث، يقوم بإعادة تحميل الصفحة وهذا هو السبب في أنه يجب عليك وضع alert("") فقط بعد التعليمات البرمجية لمنع إعادة الشحن.

يمكنك ببساطة استخدام <input type="button" value="something"> بدلا من <button></button> لمنع المتصفح من إعادة تحميل الصفحة.

كان لدي نفس المشكلة وأضاف ببساطة:

    <?php
    usleep(200000)// 2 seconds

?>

بعد JavaScript (الذي راجع للشغل، ينطوي على jQuery 1.9.1 إلى الرأس

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top