كيفية استخدام preventDefault () أو stopPropagation () بشكل صحيح أو إرجاع false ؛ في الأحداث

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

لذلك اليوم سنتعرف على الاختلافات بين الثلاثة ، وكيف تعمل بالضبط.

preventDefault () ، stopPropagation () ، وإرجاع false ؛ ليست قابلة للتبديل ، ولا هي أدوات للتجربة والخطأ.

سنبدأ بنمط واجهة مستخدم شائع جدًا - لوحة تحميل ملف - ونرى كيف يؤثر كل منها على سلوكه.

الصورة مجاملة من FineUploader

HTML

يتكون HTML الخاص بنا من ثلاثة أجزاء:

  1. مدخلات للتعامل مع مربع حوار تحميل الملف. هذا مخفي (عرض: لا شيء ؛) ، حيث أننا سنشغل مربع حوار التحميل باستخدام العنصرين التاليين.
  2. قسم يحتوي على فئة من file-upload__dropzone التي تعمل باعتبارها "منطقة الإفلات" الرئيسية حيث سنكون قادرين على سحب وإفلات الملفات (الكود غير مدرج) أو انقر لفتح مربع حوار تحميل الملف.
  3. علامة مع فئة file-upload__btn - تحميل والذي سيكون بمثابة زر "تحميل الملفات" ، والذي عند النقر عليه سيفتح مربع حوار تحميل الملف.

جافا سكريبت

يتكون JavaScript الخاص بنا ، مثل HTML ، من ثلاثة أجزاء:

  1. وظيفة fileUpload لتشغيل حدث النقر على مدخلات تحميل الملف.
  2. تعيين div dropzone وزر للمتغيرات.
  3. إضافة مستمعي الأحداث إلى هؤلاء ، والتي عند النقر فوقها ، تستدعي وظيفة fileUpload.

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

event.preventDefault ()

يمنع السلوك الافتراضي للمتصفحات (مثل فتح الرابط) ، لكنه لا يمنع الحدث من ظهور فقاعة DOM.

في السيناريو الخاص بنا ، يؤدي النقر فوق الزر "تحميل الملفات" إلى استدعاء وظيفة fileUpload ، كما هو متوقع.

لكونه علامة ، فإنه يحتوي أيضًا على سلوك افتراضي - يتمثل في التنقل في المتصفح إلى الموقع في سمة href. في هذه الحالة ، لدينا هذه المجموعة على # ، والتي في معظم المتصفحات ستتسبب فقط في عودة الصفحة إلى الأعلى.

إن القفز مرة أخرى إلى أعلى الصفحة ليس سلوكنا المنشود حقًا ، لذا يمكننا منع ذلك باستخدام طريقة preventDefault. هذا يمنع السلوك الافتراضي لأحد العناصر.

عند تعديل شفرة JavaScript الخاصة بنا ، يمكننا إصلاح ذلك بحيث يؤدي النقر فوق الارتباط إلى منع السلوك الافتراضي للانتقال إلى الموقع في سمة href ، ولكن لا يزال يفتح مربع حوار تحميل الملف.

هنا أخذنا حدث النقر ومنعنا سلوكه الافتراضي باستخدام event.preventDefault () ، ثم استدعينا وظيفة fileUpload ().

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

event.stopPropagation ()

يمنع الحدث من نشر DOM ، لكنه لا يوقف السلوك الافتراضي للمتصفحات.

للحصول على شرح متعمق لبث الأحداث ، أوصي بهذا المقال حول نشر الحدث. ولكن في الأساس ، عندما يتم استدعاء الحدث على عنصر ما ، فإن هذا الحدث يندفع إلى DOM ويستدعي إلى جميع العناصر الوالدية.

في حالتنا ، هذا يعني أنه عند النقر فوق الزر "تحميل الملف" ، يتم استدعاء حدث النقر هذا أيضًا إلى جميع عناصره الرئيسية ، بما في ذلك منطقتنا المنسدلة.

لنرى ذلك أثناء العمل ، يمكننا إزالة استدعاء fileUpload () في مستمع أحداث الزر وستظل الوظيفة قابلة للاستدعاء عندما نضغط على الزر لأن حدث النقرات سوف ينطلق من DOM ويتم استدعاؤه في القائمة المنسدلة.

تمثل هذه الفقاعة مثالًا على نشر الأحداث ، حيث يتم تشغيل طريقة stopPropagation. يمكننا استخدامه لمنع هذا السلوك الفقاعي الافتراضي بحيث يتم تسجيل الحدث فقط من خلال العنصر الذي يتم استدعاؤه.

الآن نرى أن حدث النقر لا يقتصر فقط على فتح DOM ، ولكن عن طريق إزالة طريقة preventDefault ، ستعمل العلامة كما يجب مرة أخرى ، من خلال الانتقال إلى سمة href الخاصة بها.

لكن هذا ليس ما نريد. أردنا استدعاء وظيفة fileUpload وأيضًا منع السلوك الافتراضي للعنصر ومنع الحدث من تكوين DOM.

يمكننا استخدام كل من blockDefault و stopPropagation ثم استدعاء وظيفة fileUpload ، على هذا النحو.

عودة كاذبة؛

يشاهد عادةً في كود jQuery ، ويمنع السلوك الافتراضي للمتصفحات ، ويمنع الحدث من الظهور على DOM ، ويعود على الفور من أي رد اتصال.

في vanilla JavaScript ، لا يكون لإرجاع false أي تأثير على السلوك الافتراضي أو نشر الحدث للعنصر ، كما نرى هنا ، إنه يعمل تمامًا كما كان يفعل في البداية.

إنه يستدعي حدث النقر على الزر ، وينتقل أيضًا إلى قيمة href ، ثم ينفخ DOM ، ويدعو إلى حدث النقر في المنطقة المنسدلة أيضًا.

ومع ذلك…

... في سياق jQuery ، سيؤدي إرجاع false إلى الخروج فورًا من رد اتصال مستمعي الحدث. هذا له تأثير كلا:

  1. منع السلوك الافتراضي - التنقل في المتصفح إلى سمة href للعلامة.
  2. إيقاف أي نشر للحدث - إيقاف حدث النقر من ظهور فقاعة DOM.

إذا قمنا بإعادة تأكيد كودنا على jQuery ، فيمكننا رؤية ذلك في الممارسة العملية.

نحن نسمي طريقة fileUpload ، ثم نرجع خطأ لمنع أي سلوك أو نشر حدث افتراضي.

استنتاج

يجب أن نستخدم هذه الأدوات بشكل صحيح وحكيم.

في المرة التالية التي نواجه فيها هذا النوع من المواقف ، يجب ألا نلعب فقط مع event.preventDefault () و event.stopPropagation () ونعود كاذبة ؛ حتى نحصل على النتيجة المرجوة.

يجب أن نفكر في ما نريد تحقيقه ، وكيفية الوصول إليه - ليس من خلال التجربة والخطأ والحظ - ولكن من خلال التفكير في المشكلة وتطبيق الحل الصحيح.