لدي مشاكل في حدث Keydown والإكمال التلقائي في Firefox على Mac

StackOverflow https://stackoverflow.com/questions/2303955

سؤال

هذا يقودني المكسرات. من الصعب شرحه لكنني سأذهب.

لدي حقل نص إدخال واحد في الصفحة الأولى من موقعي. لقد قمت بترميز مراقب حدث keydown الذي يتحقق من رمز المفاتيح وإذا أدخله (أو equiv) ، فهو يتحقق من قيمة الإدخال (البريد الإلكتروني). إذا كان البريد الإلكتروني صالحًا وفريدًا في DB IT ، فسيقوم بإرسال النموذج. الأشياء الأساسية ، أو هكذا تعتقد.

إذا قمت بكتابة عنوان بريدي الإلكتروني في الحقل وضغط على Enter ، فهو يعمل بشكل جيد في جميع المتصفحات. ومع ذلك ، إذا قمت بكتابة أول زوجين من الرسائل ، ثم استخدم مفاتيح الأسهم لتحديد البريد الإلكتروني من مربع القائمة المنسدلة History (آمل أن تعرف ما أعنيه هنا) ، ثم اضغط على Enter للنتيجة مختلفة. يتم التقاط قيمة حقل النموذج كضمان من الرسائل التي كتبتها ، وبالتالي فإن التحقق من الصحة يفشل. يبدو أنه عندما أضغط على مفتاح Enter "لتحديد" البريد الإلكتروني من القائمة المنسدلة ، فإن المتصفح يقاطع ذلك كما لو كنت أكتب.

في Chrome و Safari يعمل كما ينبغي. كما ينبغي أن يعني أنه عند الضغط على Enter "لتحديد" البريد الإلكتروني من القائمة المنسدلة ، فإن كل ما يفعله هو وضع عنوان البريد الإلكتروني في مربع النص. فقط على مفتاح Enter Second ، هل تقوم بإطلاق مراقب الحدث ، ويتم التحقق من صحة البريد الإلكتروني.

آمل أن يتمكن شخص ما من إلقاء بعض الضوء على سبب حدوث ذلك ... شعوري الغريزي هو أمر متصفح وسيكون شيئًا لا أستطيع إصلاحه.

شكرا لي

تحرير: لإضافة توضيح إلى سؤالي ، اسمحوا لي أن أضيف أن IM باستخدام حدث "KeyDown" لالتقاط اللحظة التي يتم فيها الضغط على مفتاح Enter. لقد جربت حدث "keyup" وهذا حل مشكلتي أعلاه ، ولكن بعد ذلك ، لا يمكنني إيقاف النموذج الذي يقدمه بنفسه. يحضر حدث "keyup" بعد السلوك الافتراضي ، وبالتالي ليس الخيار الصحيح لهذا الغرض.

مزيد من التحرير:

شكرًا لك مرة أخرى ، و BTW ، لغتك الإنجليزية ممتازة (استجابةً لتعليقك حول اللغة الإنجليزية السيئة).

لقد غيرت معالج الحدث الخاص بي من هذا:

$("emailInputBox").observe("keydown", function(event) {
    return submitViaEnter(event, submitSignupFormOne);
});

الى هذا:

$("emailInputBox").observe("keydown", function(event) {
    setTimeout(submitViaEnter.curry(event, submitSignupFormOne),0);
});

submitViaEnter:

function submitViaEnter(event, callback) {
var code = event.keyCode;
if (code == Event.KEY_RETURN) {
    event.stop();
    return callback(event);
}
return true;
}

يبدو أنها تعمل ولكن المشكلة الآن هي أنه يُسمح للمتصفح بتنفيذ الإجراء الافتراضي قبل تشغيل submitViaEnter الوظيفة مما يعني أن النموذج يتم تقديمه عندما أضغط على Enter.

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

المحلول

أجب على السؤال الأصلي

نعم ، إنه علة Gecko (وليس Mac محددة).

الجزء الأخير من هذا التعليق يحتوي على وصف للعمل: استخدم المهلة.

تحرير] منذ أن طلبت توضيح الخلل

عندما تضغط على Enter وتكون الإكمال التلقائيًا نشطًا ، يقوم Firefox (خطأً) أولاً بإطلاق معالج مفتاح الصفحة ، ثم معالج المفتاح الداخلي للمتصفح الذي يغلق المنبثقة الإضافية ويقوم بتحديث قيمة منطقة النص ، في حين أنه ينبغي أن يطلق النار عليه في المنبثقة الإكمال التلقائي ودع الصفحة فقط تعرف قيمة مربع النص.

هذا يعني أنه عندما يتم استدعاء معالج المفاتيح الخاص بك ، فإن معالج الإكمال التلقائي لم يتم تشغيله بعد-لا تزال المنبثقة الإكمال التلقائي مفتوحًا وكانت قيمة مربع النص كما كانت قبل حدوث الإكمال التلقائي.

عند إضافة أ setTimeout اتصل بمعالج المفاتيح الذي تقوله للمتصفح "مهلا ، قم بتشغيل هذه الوظيفة مباشرة بعد الانتهاء من القيام بالأشياء بالفعل في قائمة P1 الخاصة بك". لذا ، يعمل معالج الإكمال التلقائي ، لأنه موجود بالفعل في قائمة المهام ، ثم يتم تشغيل الرمز الذي تضعه في مهلة-عند إغلاق المنبثقة الإكمال التلقائي بالفعل وتحديث قيمة مربع النص.

تحرير] الإجابة على السؤال في "تحرير آخر"

حق. تحتاج إلى إلغاء الإجراء الافتراضي في معالج الأحداث ، وليس في المهلة ، إذا كنت تريد أن تعمل:

function onKeyPress(ev) {
  if (... enter pressed ...) {
    setTimeout(function() {
      ... check the new textbox value after letting autocomplete work ...
    }, 0);
    // but cancel the default behavior (submitting the form) directly in the event listener
    ev.preventDefault();
    return false;
  }
}

إذا كنت لا تزال ترغب في إرسال النموذج عند Enter ، فسيكون ذلك تمرينًا أكثر إثارة للاهتمام ، لكن لا يبدو أنك تفعل ذلك.

نصائح أخرى

طيب فرزها. شكرا جزيلا لمساعدتكم. كانت وظيفة الكاري التي كنت في عداد المفقودين من قبل. كنت أحاول العمل في الحدث داخل نطاق وظيفة setTimeout.

هذا يعمل أدناه. يتم استدعاء Sumpviaenter من EventObserver ويستجيب لحدث Keydown:

function submitViaEnter(event, callback) {
var code = event.keyCode;
if (code == Event.KEY_RETURN) {
    event.stop();
    setTimeout(callback.curry(event),0);        
    // return callback(event);
    // return false;    
}
return true;
}

يعني إيقاف الإجراء الافتراضي داخل EventObserver أنه لا يمكن كتابة أي شخصيات. لذلك علقت داخل شرط مفتاح إدخال IF.

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