اليوم، عند تطوير صفحة H5 للجوال، واجهت مشكلة عدم قدرة الواجهة على العودة إلى وضعها الأصلي عند سحب لوحة المفاتيح على نظام IOS. يتم وصف المشاكل والأعراض بالتفصيل أدناه:
هيكل الصفحةالصفحة المعنية عبارة عن بنية نموذج. أي أنه يشبه بنية تحتوي على أربعة نماذج إدخال ضمن div للمستخدمين لملء المعلومات البريدية. مشابه:
<div> <input type=text placeholder=يرجى ملء المقاطعة والمدينة والمقاطعة/> <input type=text placeholder=يرجى ملء العنوان/> <input type=text placeholder=يرجى ملء الاسم/> < نوع الإدخال=العنصر النائب للنص=يرجى ملء العنوان/رقم الاتصال/></div>
لقطة الشاشة هي كما يلي:
تتحرك الصفحة تلقائيًا لأعلى عند رفع لوحة المفاتيحعندما يقوم المستخدم بإدخال رقم جهة الاتصال على الهاتف المحمول، ستظهر لوحة مفاتيح iPhone في هذا الوقت، من أجل السماح للمستخدم برؤية مربع إدخال الهاتف، سيتم نقل الصفحة بأكملها لأعلى على iPhone (وإلا فإن لوحة المفاتيح). سيغطي صندوق إدخال الهاتف). في هذا الوقت، يكون الجزء العلوي من الصفحة في الواقع جزءًا من المسافة بعيدًا عن إطار العرض الخاص بنا (نرى صفًا من مربعات الإدخال يختفي من الواجهة).
لا يمكن استعادة الصفحة إلى وضعها الأصلي عند إغلاق لوحة المفاتيحومع ذلك، عندما يكمل المستخدم الإدخال ويغلق لوحة المفاتيح، على الرغم من وضع لوحة المفاتيح جانبًا، لن تتم استعادة موضع الصفحة.
تحليل المشكلةفي الواقع، يحدث هذا بسبب عدم قدرة نظام التشغيل iOS على منع جزء الصفحة من التمرير خارج إطار العرض من السقوط عند سحب لوحة المفاتيح. في هذا الوقت، يمكن للمستخدم سحب الصفحة مرة أخرى بإصبعه.
لكن التجربة لم تكن جيدة على كل حال.
لحل هذه المشكلة، يمكننا استدعاء window.scrollTo(0, 0) عندما يغادر مؤشر المستخدم مربع الإدخال لتمرير الصفحة لتتماشى مع الجزء العلوي من إطار العرض، وبالتالي تحقيق تأثير الصفحة الرئيسية.
إذن المشكلة الآن هي إضافة أحداث تمويه إلى جميع مربعات الإدخال الأربعة في النموذج، ثم استدعاء window.scrollTo في المعالج. ومع ذلك، سواء تمت إضافتها من خلال @blur الخاص بـ Vue أو من خلال عمليات DOM، فيجب إضافة 4 مستمعين للحدث، وهو أمر غير أنيق للغاية. وبطبيعة الحال، فكرنا في استخدام وكلاء الأحداث.
أي أننا نضع مستمع الحدث في العنصر العلوي، ثم نحدد دالة inputBlur لانتظار التشغيل.
<div @blur=inputBlur> <input type=text placeholder=يرجى ملء المقاطعة والمدينة والمقاطعة/> <input type=text placeholder=يرجى ملء العنوان/> <input type=text placeholder=يرجى ملء الاسم/> <input type=text placeholder=يرجى ملء رقم الاتصال الخاص بك/></div>
ونتيجة لذلك، وجدنا أن مستمع الحدث الخاص بنا فشل في إطلاقه. والسبب هو أن حدث blur الخاص بمربع الإدخال لا يمكن أن يحدث فقاعات.
بعد الاستعلام، وجد أن حدثي DOM focus blur لا يمكن أن يحدثا فقاعة في المواصفات. على غرار هذا، هناك حدثان آخران focusin focusout يمكن أن يحدثا فقاعات.
ذكرت بعض المقالات على الإنترنت أن focusin و focusout هما حدثان DOM مدعومان فقط بواسطة متصفحات IE. في الواقع، عندما ننظر إلى مستند MDN، نجد أن هذين الحدثين أصبحا معيارًا في مواصفات DOM 3، ويدعمهما عدد كبير من المتصفحات.
لذلك، لحل المشكلة بشكل حاسم من خلال هذين الحدثين، قمنا بتغييرها focusout
<div @focusout=inputBlur> <input type=text placeholder=يرجى ملء المقاطعة والمدينة والمقاطعة/> <input type=text placeholder=يرجى ملء العنوان/> <input type=text placeholder=يرجى ملء الاسم/> <input type=text placeholder=يرجى ملء رقم الاتصال الخاص بك/></div>
ثم قم بتنفيذ معالج الأحداث الخاص بنا:
inputBlur(e) { // أولاً، حدد ما إذا كان العنصر الهدف الذي يطلق الحدث هو مربع إدخال أم لا، ونحن نركز فقط على سلوك مربع الإدخال. if (e && e.target && e.target.tagName && e.target.tagName.toLowerCase() === 'input') { window.scrollTo(0,0 });في هذا الوقت، تم حل مشكلتنا. عند إدخال المحتوى من مربع الإدخال ثم النقر فوق "إنهاء" على لوحة المفاتيح لإغلاق لوحة المفاتيح، يتماشى التأثير مع توقعاتنا.
ومع ذلك، بعد الاختبار على الهواتف المحمولة، وجدنا أنه عندما ننتقل مباشرة من 电话输入框إلى 姓名输入框، فإن الصفحة سوف تهتز. دعونا نواصل التحليل.
في الواقع، السبب وراء ارتعاش صندوقي الإدخال عند التبديل بسيط جدًا أيضًا. لأنه عندما نقوم بالتبديل بين مربعي الإدخال أعلاه، ستقوم الصفحة أولاً بتشغيل حدث blur 电话输入框، ثم تشغيل حدث focus 姓名输入框. في هذه الحالة، عند حدوث التمويه، سيتم تشغيل window.scrollTo(0,0) الخاص بنا، مما يؤدي إلى تمرير الصفحة لأسفل، ثم سيتم التركيز على 姓名输入框، وبالتالي ستستمر لوحة المفاتيح في الظهور --- هذا سيؤدي إلى تحرك الصفحة لأعلى مرة أخرى.
في الواقع، عند التبديل بين مربعي إدخال، لا نحتاج إلى تشغيل سلوك window.scrollTo عندما يكون مربع الإدخال الأول غير واضح. لذلك دعونا نعدل الكود الخاص بنا بحيث أنه عند حدوث عملية تبديل صندوق الإدخال، يمكن قطع سلوك صندوق الإدخال الأول. هنا نستخدم setTimeout لحل:
<div @focusout=inputBlur @focusin=inputFocus> <نوع الإدخال=العنصر النائب للنص=يرجى ملء المقاطعة والمدينة والمقاطعة/> <نوع الإدخال=العنصر النائب للنص=يرجى ملء العنوان/> <نوع الإدخال=العنصر النائب للنص= يرجى ملء الاسم/> < input type=text placeholder=يرجى ملء رقم الاتصال الخاص بك/></div>
inputBlur(e) { // أولاً، حدد ما إذا كان العنصر الهدف الذي يطلق الحدث هو مربع إدخال أم لا، ونحن نركز فقط على سلوك مربع الإدخال. if (e && e.target && e.target.tagName && e.target.tagName.toLowerCase() === 'input') { // يفقد مربع الإدخال التركيز، ويجب دفع لوحة مفاتيح IOS خارج المربع التمرير جزء من الصفحة لاستعادته. قم بتمرير الصفحة إلى أعلى النافذة وقم بمحاذاتها console.log('set timer') this.timer = setTimeout(() => { console.log('timer Trigger') window.scrollTo(0,0); }, 0) } }, inputFocus(e) { // في حالة التركيز، قم بإزالة مؤقت مربع الإدخال السابق if (e && e.target && e.target.tagName && e.target.tagName.toLowerCase() === 'input') { ClearTimeout(this.timer);ما ورد أعلاه هو المحتوى الكامل لهذه المقالة وآمل أن يكون مفيدًا لدراسة الجميع وآمل أيضًا أن يدعم الجميع شبكة VeVb Wulin.