it-swarm.dev

onclick () و onblur () ترتيب المشكلة

لدي حقل إدخال يعرض قائمة منسدلة مخصصة. أريد الوظيفة التالية:

  • عندما ينقر المستخدم في أي مكان خارج حقل الإدخال ، يجب إزالة القائمة.
  • إذا قام المستخدم ، على وجه التحديد ، بالنقر فوق div داخل القائمة ، فيجب إزالة القائمة ، ويجب أن تتم المعالجة الخاصة بناءً على div التي تم النقر فوقها).

إليكم تنفيذي:

يحتوي حقل الإدخال على حدث onblur() والذي يحذف القائمة (عن طريق تعيين innerHTML الخاص بوالديه على سلسلة فارغة) كلما نقر المستخدم خارج حقل الإدخال. تحتوي divs داخل القائمة أيضًا على أحداث onclick() التي تنفذ المعالجة الخاصة.

المشكلة هي أن أحداث onclick() لن تنطلق أبدًا عند النقر فوق القائمة ، لأن onblur()__وظيفة الحقل المدخلة تشتعل أولاً وتحذف القائمة ، بما في ذلك onclick()s!

لقد حللت المشكلة بتقسيم onclick() divs في القائمة إلى onmousedown() و onmouseup() وضبط علامة عمومية على الماوس لأسفل والتي يتم مسحها على الماوس لأعلى ، على غرار ما اقترح في هذه الإجابة . نظرًا لأن onmousedown() تشتعل قبل onblur() ، سيتم تعيين العلامة في onblur() إذا تم النقر فوق أحد divs القائمة ، ولكن ليس إذا كان هناك مكان آخر على الشاشة. إذا تم النقر فوق القائمة ، فسوف أعود على الفور من onblur() دون حذف القائمة ، ثم انتظر onclick() لإطلاق النار ، وعند هذه النقطة يمكنني حذف القائمة بأمان.

هل هناك حل أكثر أناقة؟

يبدو الرمز كالتالي:

<div class="menu" onmousedown="setFlag()" onmouseup="doProcessing()">...</div>
<input id="input" onblur="removeMenu()" ... />

var mouseflag;

function setFlag() {
    mouseflag = true;
}

function removeMenu() {
    if (!mouseflag) {
        document.getElementById('menu').innerHTML = '';
    }
}

function doProcessing(id, name) {
    mouseflag = false;
    ...
}
73
1''

كنت أواجه نفس المشكلة تمامًا مثلك ، تم تصميم واجهة المستخدم الخاصة بي تمامًا كما تصفها. لقد قمت بحل المشكلة ببساطة عن طريق استبدال onClick لعناصر القائمة مع onMouseDown. لم أفعل شيئًا آخر ؛ لا onMouseUp ، لا أعلام. أدى هذا إلى حل المشكلة عن طريق السماح للمتصفح بإعادة الطلب تلقائيًا وفقًا لأولوية معالجات الأحداث هذه ، دون أي عمل إضافي من جانبي.

هل هناك أي سبب لماذا هذا لن تعمل أيضا بالنسبة لك؟

125
johnbakers

استبدل on onmousedown with onfocus . لذلك سيتم تشغيل هذا الحدث عندما يكون التركيز داخل مربع النص.

استبدل on onmouseup with onblur . في اللحظة التي تأخذ بها تركيزك خارج مربع النص ، سيتم تنفيذ onblur.

أعتقد أن هذا هو ما قد تحتاجه.

UPDATE:

عند تنفيذ وظيفتك على التركيز -> إزالة الفئات التي ستطبقها في onblur وإضافة الفئات التي تريد تنفيذها على التركيز

و

عندما تقوم بتنفيذ وظيفتك onblur -> قم بإزالة الفئات التي ستطبقها عند التركيز وقم بإضافة الفئات التي تريد تنفيذها على blbl

لا أرى أي حاجة لمتغيرات العلم.

تحديث 2:

يمكنك استخدام الأحداث onmouseout و onmouseover

onmouseover- يكتشف عندما يكون المؤشر فوقه.

onmouseout- يكتشف عندما يغادر المؤشر.

4
HIRA THAKUR

حل أكثر أناقة (ولكن من المحتمل أن يكون أقل أداءً):

بدلاً من استخدام onblur للمدخلات لإزالة القائمة ، استخدم document.onclick ، الذي ينطلق بعد onblur.

ومع ذلك ، هذا يعني أيضًا أن القائمة قد تمت إزالتها عند النقر فوق الإدخال نفسه ، وهو سلوك غير مرغوب فيه. قم بتعيين input.onclick مع event.stopPropagation() لتجنب نشر النقرات على حدث النقر فوق المستند.

2
1''

تغيير onclick بواسطة onfocus

حتى لو كان onblur و onclick لا يتماشيان جيدًا ، لكن من الواضح أنهما يركزان ونعم onblur. لأنه حتى بعد إغلاق القائمة ، فإن onfocus لا يزال صالحًا للعنصر الذي تم النقر عليه بالداخل.

لقد فعلت وانها عملت.

0
Brasil