بمجرد أن بدأت أداة معالجة الحدث

اختبار سريع: ما هو الغرض من المعلَمة الثالثة التي تم تمريرها إلى addEventListener()؟

لا داعي للخجل إذا كنت تعتقد أنّ addEventListener() لا يأخذ سوى مَعلمتَين، أو ربما تضبط دائمًا قيمة false بشكلٍ ثابت، مع فهمٍ ملتبسٍ بأنّ ذلك له علاقة… بالفقاعات؟

دالة addEventListener()‎ أكثر قابلية للضبط

لقد قطعت طريقة addEventListener() شوطًا طويلاً منذ الأيام الأولى للشبكة الويب، ويتم ضبط وظيفتها الجديدة من خلال إصدار مُحسَّن من تلك المَعلمة الثالثة. تسمح التغييرات الأخيرة التي تم إجراؤها على تعريف الطريقة لصنّاع التطبيقات بتقديم خيارات إضافية من خلال عنصر الضبط، مع الحفاظ على التوافق مع الإصدارات القديمة في حال توفّر مَعلمة منطقية أو في حال عدم تحديد خيار.

يسرّنا الإعلان عن أنّ الإصدار 55 من Chrome يتيح استخدام الخيار once في عنصر الضبط هذا، إلى جانب خيارَي passive (تم تنفيذه في الإصدار 51 من Chrome) وcapture (تم تنفيذه في الإصدار 49 من Chrome). على سبيل المثال:

element.addEventListener('click', myClickHandler, {
    once: true,
    passive: true,
    capture: true
});

يمكنك مزج هذه الخيارات ومطابقتها حسبما يناسب حالة الاستخدام الخاصة بك.

مزايا التنظيف بعد الانتهاء من استخدام المساحة

هذه هي بنية الجملة لاستخدام الخيار once الجديد، ولكن ما هي الفائدة التي تحقّقها؟ بعبارة أخرى، يوفّر لك أداة معالجة أحداث مخصّصة لحالات الاستخدام التي تتطلّب تنفيذ مهمة واحدة فقط.

تبقى أدوات الاستماع إلى الأحداث محفوظة تلقائيًا بعد المرة الأولى التي يتم فيها استدعاؤها، وهو ما تريده لبعض أنواع الأحداث، مثل الأزرار التي يمكن النقر عليها عدة مرات. في الاستخدامات الأخرى، ليس من الضروري أن تظل أداة معالجة الأحداث قيد الاستخدام، ويمكن أن يؤدي ذلك إلى سلوك غير مرغوب فيه إذا كان لديك أسلوب callback يجب تنفيذه مرة واحدة فقط. كان لدى المطوّرين المهتمين بالجودة دائمًا خيار استخدام removeEventListener() لتنظيف الملفات بشكل صريح، وذلك باتّباع نماذج مثل:

element.addEventListener('click', function cb(event) {
    // ...one-time handling of the click event...
    event.currentTarget.removeEventListener(event.type, cb);
});

إنّ الرمز البرمجي المكافئ الذي يستخدم المَعلمة الجديدة once أكثر وضوحًا، ويتجنّب تتبُّع اسم الحدث (event.type في المثال السابق) أو الإشارة إلى دالة الاستدعاء (cb):

element.addEventListener('click', function(event) {
    // ...one-time handling of the click event...
}, {once: true});

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

function setUpListeners() {
    var data = ['one', 'two', '...etc.'];

    window.addEventListener('load', function() {
    doSomethingWithSomeData(data);
    // data is now part of the callback's scope.
    });
}

سيظلّ المرجع المخصّص لاستدعاء مستمع أحداث load ضمن النطاق تلقائيًا عند انتهاء تشغيله، حتى لو لم يتم استخدامه مرة أخرى. وبما أنّ المتغيّر data يُستخدَم داخل دالة الاستدعاء، سيظلّ أيضًا ضمن النطاق، ولن يتم جمع القمامة مطلقًا. في حال إزالة دالة ردّ الاتصال من خلال المَعلمة once، قد يكون كلّ من الدالة نفسها وأيّ عنصر يتم الاحتفاظ به من خلال نطاقها مؤهّلاً لجمع المهملات.

دعم المتصفح

يتوفّر دعم أصلي لاستخدام الخيار once في الإصدار 55 من Chrome والإصدار 50 من Firefox والإصدار 7 من معاينة التكنولوجيا من Safari والإصدارات الأحدث.

توفّر العديد من مكتبات واجهة المستخدم في JavaScript طرقًا سهلة لإنشاء معالجي الأحداث، وبعضها يتضمّن اختصارات لتحديد الأحداث لمرة واحدة، وأبرزها طريقة one() في jQuery. يتوفّر أيضًا polyfill كجزء من مكتبة dom4 التي أنشأها Andrea Giammarchi.

شكرًا

نشكر Ingvar Stepanyan على ملاحظاته بشأن رمز النموذج في هذه المشاركة.